使用以下两个版本的单例类有什么区别
首先,我使用synchronized(singleton.class)
在第二个示例中,我使用synchronized(obj)//第一个类型的公共类singleton{
private static Singleton obj = null;
Singleton() {
}
public static Singleton getInstance() {
synchronized(Singleton.class){
if (obj == null) {
obj = new Singleton();
}
}
return obj;
}
}
//第二类
public class Singleton {
private static Singleton obj = null;
Singleton() {
}
public static Singleton getInstance() {
synchronized(obj){
if (obj == null) {
obj = new Singleton();
}
}
return obj;
}
}
4条答案
按热度按时间yfjy0ee71#
它们实际上是相同的,而且是一个糟糕的实现,因为obj为null(在您的示例中)并且代码每次调用都是单线程的。它应该使用双重检查锁。。。
第二个应该是:
ep6jt1vc2#
第二个版本尝试在上同步
null
,将失败。这个synchronized
关键字尝试获取Object
引用人obj
,因为它最初是null
,您将获得NulPointerException
.gc0ot86w3#
当您使用synchronized(singleton.class)时,只有在第一次创建示例之前才会应用同步,当我们有可能在代码中运行多个线程时才会使用同步。if循环将负责在已有示例可用的情况下不创建另一个示例,通过使用这种同步方式,我们减少了大量的开销,因为我们知道同步类在时间/等待方面会增加开销。
bttbmeg04#
主要区别在于
synchronized(obj)
不起作用:你第一次叫它,obj
是null
,所以你会看到NullPointerException
.在ideone上演示。
Singleton.class
另一方面,它永远不会null
,因此可以使用它进行同步。但是,恶意代码可以执行一种攻击,使您的getInstance
方法永远等待:他们只需要锁定你的Singleton.class
,在那里无限的等待。针对此攻击的常见防御方法是为锁使用单独的私有静态对象,如下所示: