java - 无法打破经典的延迟初始化单例

标签 java multithreading singleton

我正在尝试创建各种单例模式并使用数百万个线程检查中断。我希望这能引导我最终实现比尔·皮尤(Bill Pugh)。但我什至无法打破经典。

单例:之前尝试过一百万个线程,所有线程都具有相同的哈希码。所以我让它 hibernate 10 秒,这样两个线程都肯定会进入空检查条件,但一切都令人沮丧。

package demo2;

public class Singleton {

    private static Singleton soleInstance = null;

    private Singleton() throws InterruptedException {

    }

    public static Singleton getInstance() throws InterruptedException {

        if (soleInstance == null) {

            Thread.sleep(10000);

            soleInstance = new Singleton();

        }

        return soleInstance;

    }

}

测试类:

package demo2;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

class Test {

    public int makeSingleton() throws InterruptedException {

        Singleton s = Singleton.getInstance();

        return s.hashCode();

    }

    public static void main(String[] args) throws InterruptedException, ExecutionException  {

        Test t = new Test();

        ExecutorService executor = Executors.newFixedThreadPool(2);

        List<Integer> list = new ArrayList<>();

        for (int i = 0; i < 2; i++) {

            Future<Integer> future = executor.submit(new Callable<Integer>() {

                public Integer call() throws InterruptedException {

                     return t.makeSingleton();
                }
            });

            list.add(future.get());
        }

        executor.shutdown();

        List<Integer> list2 = list.stream().distinct().collect(Collectors.toList());

        System.out.println(list2);

    }
}

我该如何破解它?

最佳答案

下面提到的代码可以工作。

更改您的代码。可能您仅在方法内部调用 get,并且它正在等待获取结果并且循环计数不会增加。

ExecutorService executor = Executors.newFixedThreadPool(2);

        List<Future<Integer>> list = new ArrayList<Future<Integer>>();

        for (int i = 0; i < 5; i++) {

            Future<Integer> future = executor.submit(new Callable<Integer>() {

                public Integer call() throws InterruptedException {

                    return Singleton.getInstance().hashCode();
                }
            });

            list.add(future);
        }

        executor.shutdown();

        Set<Integer> output = new HashSet<Integer>(); 
        for(Future<Integer> future : list){
            output.add(future.get());
        }

        System.out.println(output);

关于java - 无法打破经典的延迟初始化单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42743444/

相关文章:

java - 从jetty中的其他线程广播websocket消息

c++ - 延迟初始化?

java - 是否可以在Eclipse中设置一个子包作为源DISPLAY的根?

java - 使用带有 -clientjar 选项的 jaxws-maven-plugin

java - 为什么 EntityManager 关闭了?

java - 没有 Struts 和 Maven 的 JSP Tiles

并发加载和存储

c++ - 从多个线程为同一 vector 的不同范围调用 std::copy 是否安全?

android - 从覆盖的 getApplication() 返回共享静态是否安全?

c# - 我有一个 Singleton 类,但返回两个。我需要两个 lok 对象吗?