同步(Singleton.class)和同步(obj)之间的java差异
使用以下两个版本的单例类之间有什么区别
首先,我使用的是synchronized(Singleton.class)
在第二次使用同步(Obj) //第一类 公营单身人士{
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;
}
}
# 1 楼答案
第二个版本尝试在
null
上同步,但将失败。synchronized
关键字尝试获取由obj
引用的Object
上的锁,由于它最初是null
,您将得到一个NulPointerException
# 2 楼答案
它们实际上是相同的,而且是一个糟糕的实现,因为obj为NULL(在您的示例中),并且代码每次调用都是单线程的。它应该使用双重检查锁
第二个应该是:
# 3 楼答案
当您使用synchronized(Singleton.class)时,只有在第一次创建实例之前才会应用同步,当我们有可能在代码中运行多个线程时才会使用同步。如果已经有一个实例可用,您的if循环将负责不创建另一个实例,通过使用这种同步方式,我们减少了大量的开销,因为我们知道同步类在时间/等待方面会增加开销
# 4 楼答案
主要的区别是
synchronized(obj)
不起作用:第一次调用它时,obj
是null
,所以你会看到一个NullPointerException
Demo on ideone.
另一方面
Singleton.class
永远不会是null
,所以可以使用它进行同步。然而,恶意代码可以执行一种攻击,使getInstance
方法永远等待:它们只需锁定Singleton.class
,并在那里无限等待针对这种攻击的常见防御措施是为锁使用单独的私有静态对象,如下所示: