单线程在多线程 - 各种场景

时间:2011-07-07 19:26:29

标签: java multithreading singleton

以下两个代码在多线程环境方面有何不同?

代码1:

public class Singleton {
private Singleton() {}

private static class SingletonHolder { 
    private static final Singleton INSTANCE = new Singleton();
}

public static Singleton getInstance() {
    return SingletonHolder.INSTANCE;
}
}

代码2:

class Singleton {
private static Singleton uniqueInstance;

private Singleton() { ... }

public static Singleton getInstance() {
    if (uniqueInstance == null) {
        uniqueInstance = new Singleton();
    }

    return uniqueInstance;
}
}

为什么Code 2在多线程环境中不起作用,当它还声明了静态变量时,一旦加载了类就会加载它因此它只有一个实例?

谢谢!

2 个答案:

答案 0 :(得分:4)

请记住,多个线程可以在给定时间调用getInstance

在示例1中,uniqueInstance成员的初始化程序保证只运行一次 - 在类加载时。

在示例2中,由于初始化在getInstance内联进行,因此多个线程可以独立并同时找到uniqueInstance成员变量为null。然后每个线程将调用new Singleton(),其结果取决于两个(或更多)线程的时间。

要使示例2起作用,您可以(例如)在synchronized方法上添加getInstance

关于在类加载时初始化完全变量的注释对于示例1是正确的,但对于2没有 - 在示例2中,成员变量在类加载时设置为null在第一次调用getInstance期间,时间,但后来填充了一个对象实例。

答案 1 :(得分:1)

多个线程可能位于:

if (uniqueInstance == null) {
...
}

同时处理。