Singleton 设计模式中的 Synchronized(MyClass.class){ } - 它有什么作用?
Synchronized(MyClass.class){ } in Singleton Design Pattern - What does it do?
我正在学习设计模式并且在 Java 方面有中级经验。我正在尝试实现 Singleton 设计模式并在方法中遇到以下代码:
public static Singleton getInstance(){
if( firstInstance == null ){
if (firstThread){
firstThread = false;
Thread.currentThread();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(Singleton.class.getName()).log(Level.SEVERE, null, ex);
}
}
synchronized(Singleton.class){
if(firstInstance == null){
firstInstance = new Singleton();
}
}
}
return firstInstance;
}
我了解该方法的工作原理,但我对这段代码的一个特定部分有疑问:
synchronized(Singleton.class){
if(firstInstance == null){
firstInstance = new Singleton();
}
}
我知道 synchronized 块只强制这部分代码同步,这使得实现线程安全并且不会减慢整个方法,但为什么我们要包装 Singleton.class
在访问修饰符前的括号中 synchronized
?
我的问题与 Java 相关,而不是与设计模式相关。我尝试搜索 Google 和 Whosebug,但我不确定这实际上叫什么限制了我的结果。
希望大家能帮帮我。
提前致谢!
因为在 Java 中同步的正常对象是 this
(例如当前实例)。但是这个方法是static
,所以没有实例,只有一个class。因此我们同步了。
synchronizing
这部分方法的原因是两个实例不会同时由两个线程创建。如果两者同时进行 firstInstance == null
检查,并且在发现它是 true
时,都决定创建一个新实例,则可能会发生这种情况。这给了我们一个 Singleton
class 的两个实例,这显然非常糟糕。
另外,我认为您将 synchronized
称为 access modifier 时感到困惑。
唯一的访问修饰符是 private
、public
和 protected
(加上隐藏的默认修饰符)。
Synchronized
是一个 non-access modifier。单个方法可以同时具有访问和非访问修饰符,例如 public static
或 private synchronized
.
请注意,只有 synchronized
和 static
可以有块。然而,这更多是因为它们的用途,而不是它们的修饰符 class化。
firstInstance 变量可能是 Singleton class 中的静态变量,包含该 class 的唯一对象。
在 class 上同步可确保两个不同的线程不会同时尝试创建 firstInstance 对象。这确保了 firstInstance 变量只被初始化一次。
我正在学习设计模式并且在 Java 方面有中级经验。我正在尝试实现 Singleton 设计模式并在方法中遇到以下代码:
public static Singleton getInstance(){
if( firstInstance == null ){
if (firstThread){
firstThread = false;
Thread.currentThread();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(Singleton.class.getName()).log(Level.SEVERE, null, ex);
}
}
synchronized(Singleton.class){
if(firstInstance == null){
firstInstance = new Singleton();
}
}
}
return firstInstance;
}
我了解该方法的工作原理,但我对这段代码的一个特定部分有疑问:
synchronized(Singleton.class){
if(firstInstance == null){
firstInstance = new Singleton();
}
}
我知道 synchronized 块只强制这部分代码同步,这使得实现线程安全并且不会减慢整个方法,但为什么我们要包装 Singleton.class
在访问修饰符前的括号中 synchronized
?
我的问题与 Java 相关,而不是与设计模式相关。我尝试搜索 Google 和 Whosebug,但我不确定这实际上叫什么限制了我的结果。
希望大家能帮帮我。
提前致谢!
因为在 Java 中同步的正常对象是 this
(例如当前实例)。但是这个方法是static
,所以没有实例,只有一个class。因此我们同步了。
synchronizing
这部分方法的原因是两个实例不会同时由两个线程创建。如果两者同时进行 firstInstance == null
检查,并且在发现它是 true
时,都决定创建一个新实例,则可能会发生这种情况。这给了我们一个 Singleton
class 的两个实例,这显然非常糟糕。
另外,我认为您将 synchronized
称为 access modifier 时感到困惑。
唯一的访问修饰符是 private
、public
和 protected
(加上隐藏的默认修饰符)。
Synchronized
是一个 non-access modifier。单个方法可以同时具有访问和非访问修饰符,例如 public static
或 private synchronized
.
请注意,只有 synchronized
和 static
可以有块。然而,这更多是因为它们的用途,而不是它们的修饰符 class化。
firstInstance 变量可能是 Singleton class 中的静态变量,包含该 class 的唯一对象。
在 class 上同步可确保两个不同的线程不会同时尝试创建 firstInstance 对象。这确保了 firstInstance 变量只被初始化一次。