无法打破经典的懒惰初始化Singleton

时间:2017-03-12 03:35:26

标签: java multithreading singleton

我正在尝试创建各种单例模式,并使用数百万个线程检查中断。我希望这会让我最终实施Bill Pugh。但我甚至无法打破经典之作。

Singleton:之前尝试过一百万个线程,所有线程都有相同的哈希码。所以我让它睡了10秒钟,这样两个线程肯定都会进入无效检查状态,但都是沮丧。

for I in doc.paragraphs: 
    if I in string: 
        doc.paragraphs.remove(I)

测试类:

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;

    }

}

我该怎么打破它?

2 个答案:

答案 0 :(得分:2)

下面提到的代码可以使用。

更改您的代码。可能是你只是在调用内部方法而且它正在等待获得结果&循环计数不会增加。

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);

答案 1 :(得分:1)

请检查:

/**
 * <p>
 * If you would like to immediately block waiting
 * for a task, you can use constructions of the form
 * {@code result = exec.submit(aCallable).get();}
 */
<T> Future<T> submit(Callable<T> task);

如果您使用

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

它会阻止你的线程,直到结果返回。

如果您想打破传统的单例模式,请尝试使用此代码

public class BreakSingleton {

    public MySingleton makeSingleton() throws InterruptedException {
        MySingleton s = MySingleton.getInstance();
        return s;
    }

    public static void main(String[] args) throws Exception {
        BreakSingleton t = new BreakSingleton();
        ExecutorService executor = Executors.newFixedThreadPool(2);
        final List<MySingleton> list = new ArrayList<>();
        System.out.println(Thread.currentThread().getName());

        for (int i = 0; i < 2; i++) {
            executor.submit(new Callable<MySingleton>() {
                public MySingleton call() throws InterruptedException {
                    MySingleton mySingleton = t.makeSingleton();
                    list.add(mySingleton);
                    return mySingleton;
                }
            });
        }
        executor.shutdown();
        Thread.sleep(5000);
        System.out.println(list);
    }
}

class MySingleton {
    private static MySingleton instance = null;

    private MySingleton() {
    }

    public static MySingleton getInstance() throws InterruptedException {
        System.out.println(Thread.currentThread().getName());
        if (instance == null) {
            Thread.sleep(3000);
            System.out.println(Thread.currentThread().getName());
            instance = new MySingleton();
        }
        return instance;
    }
}