Sun*_*pta 0 java multithreading
Singleton中的Double Lock检查通常写为:
public static Singleton getInstance()
{
if (instance == null)
{
synchronized(Singleton.class) { //1
if (instance == null) //2
instance = new Singleton(); //3
}
}
return instance; //4
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,假设有十个线程正在调用此方法,所有这些线程都超过了第一个if条件,然后一个线程进入synchronized块并创建实例.即使创建了实例,它们也需要等待并顺序通过synchronized块,剩下的9个线程将逐个出现.我希望只要任何线程创建Singleton实例,所有其他线程就不应该等待.告诉我是否有解决方案?
如果您坚持使用延迟实例化,我认为没有解决方案.您可以在声明instance变量时创建单例对象:
class Singleton {
private static final instance = new Singleton();
private Singleton() {} // prevent outside construction
public static Singleton getInstance() {
return instance; // no synchronization needed
}
}
Run Code Online (Sandbox Code Playgroud)
感谢eSniff的评论(以及yair的评论让我对eSniff的评论说得对),这里是维基百科中发布的一种线程安全和懒惰的方法:
class Singleton {
private static class Holder {
static final instance = new Singleton();
}
private Singleton() {} // prevent outside construction
public static Singleton getInstance() {
return Holder.instance; // no synchronization needed
}
}
Run Code Online (Sandbox Code Playgroud)
您是否测试了性能并得出了确实需要延迟初始化的明确结论?如果是这样,请使用持有人模式:
public static class Singleton {
private static class InstanceHolder {
public static Singleton instance = new Singleton();
}
private Singleton(){}
public static Singleton getInstance() {
return InstanceHolder.instance;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果你没有经过不错的性能测试,那么最简单的事情就是在其实例声明(急切初始化)中初始化单例,如下所示:
public static class Singleton {
public static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance() {
return instance;
}
}
Run Code Online (Sandbox Code Playgroud)
这两种模式允许依赖类加载过程来确保任何使用Singleton视图的线程都是一致的实例.这样您就可以获得两个好处:代码更易读,运行速度更快.
顺便说一下,Double-Check-Idiom不是线程安全的,除非你Singleton.instance声明volatile.
| 归档时间: |
|
| 查看次数: |
949 次 |
| 最近记录: |