[英]Singleton Implementation example
我正在尝试找到自己的Java Singleton实现方式。 代码如下:
public class Singleton{
private volatile static Singleton _instance = null;
private Singleton(){}
public static Singleton getInstance(){
if (_instance == null)
Object obj = new Object();
synchronized(obj){
if (_instance == null)
_instance = new Singleton();
}
return _instance;
}
此代码有效吗? 如果不起作用,该如何解决?
否-您的代码无效,因为锁对象是局部变量,因此每个线程都不同。
您正在尝试实现惰性初始化模式-首次使用实例时在其中创建实例。
但是有一个简单的技巧,可以让你编写一个线程安全的实现, 不需要同步! 它称为“ 按需初始化持有人”习惯用法 ,它看起来像这样:
public class Singleton {
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
private Singleton() {
}
// rest of class omitted
}
此代码在第一次调用getInstance()
初始化实例,并且重要的是,由于类加载器的约定,不需要同步:
Holder
的唯一访问是在getInstance()`方法内) Holder
的静态块触发时) 每当需要懒惰初始化时,我都会使用这巧妙的小技巧。 您还可以获得final
实例的奖励,甚至认为它是惰性创建的。 还要注意代码是多么干净和简单。
不懒惰的单身人士的棘手且非常简单的实现:
public enum TickySingleton {
INSTANCE;
public void doSomething() { ... }
public Object returnSomething() { ... }
}
}
不是每个人都会喜欢这样。 ;)
如果您的同步对象是final static
会更好。 否则,每个可能的并发线程将创建自己的同步对象并锁定不同的对象。 他们不会互相等待。
public class Singleton{
private final static Object obj = new Object();
private volatile static Singleton _instance = null;
private Singleton(){}
public static Singleton getInstance(){
if (_instance == null)
synchronized(obj){
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
当你写:
Object obj = new Object();
synchronized(obj){}
JVM可以证明没有两个线程可以获取该锁(因为它是局部变量),因此可以完全删除同步。
关于单例的一些评论:
不,这是不正确的,您应该在Singleton.class上进行同步
class Singleton {
private volatile static Singleton _instance;
private Singleton(){}
public static Singleton getInstance(){
if (_instance == null)
synchronized(Singleton.class){
if (_instance == null)
_instance = new Singleton();
}
return _instance;
}
}
这是一种已知的双重检查锁定模式,有关详细信息,请参见http://www.ibm.com/developerworks/java/library/j-dcl/index.html
请注意,由于此类中只有一个方法,因此以下内容可达到相同目的,而无需任何双重检查的技巧,而且它也是懒惰的
class Singleton {
private static Singleton _instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return _instance;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.