单例模式中的同步块 (Java)
Synchronized block in Singleton Pattern (Java)
我对在维基百科上找到的线程安全单例模式有疑问。
public final class Singleton {
private static volatile Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
如果synchronized块不同步,是否可以2个线程同时创建2个对象?
我需要解释一下 "synchronized" 的用法。
谢谢和最诚挚的问候
如果不同步,你确实可以让 2 个线程创建 2 个对象。
- T1:检查实例是否为空 => 是! => 继续下一行
- T2:检查实例是否为空 => 是! => 继续下一行
- T1:创建对象
- T2:创建对象
使用synchronized时,一次只能有1个线程进入synchronized阻塞。
- T1:检查实例是否为空 => 是! => 继续下一行
- T1:创建对象
- T2:检查实例是否为空 => 否! => 跳过块
编辑:
It is worth noting that the null check inside of the synchronized
block is actually very important - otherwise it would be possible to
create 2 objects as well. – Amongalen (in comments)
另一种实现单例模式的方法如下。 仅当应用程序启动后创建对象不是大问题时才使用此模式:
public final class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
我对在维基百科上找到的线程安全单例模式有疑问。
public final class Singleton {
private static volatile Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
如果synchronized块不同步,是否可以2个线程同时创建2个对象?
我需要解释一下 "synchronized" 的用法。
谢谢和最诚挚的问候
如果不同步,你确实可以让 2 个线程创建 2 个对象。
- T1:检查实例是否为空 => 是! => 继续下一行
- T2:检查实例是否为空 => 是! => 继续下一行
- T1:创建对象
- T2:创建对象
使用synchronized时,一次只能有1个线程进入synchronized阻塞。
- T1:检查实例是否为空 => 是! => 继续下一行
- T1:创建对象
- T2:检查实例是否为空 => 否! => 跳过块
编辑:
It is worth noting that the null check inside of the synchronized block is actually very important - otherwise it would be possible to create 2 objects as well. – Amongalen (in comments)
另一种实现单例模式的方法如下。 仅当应用程序启动后创建对象不是大问题时才使用此模式:
public final class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}