Nas*_*LEK 1 java multithreading synchronization design-patterns
请参阅此https://en.wikipedia.org/wiki/Double-checked_locking,我们有:
// "Double-Checked Locking" idiom
class Foo {
private Helper helper;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null) {
helper = new Helper();
}
}
}
return helper;
}
// other functions and members...
}
Run Code Online (Sandbox Code Playgroud)
第二次测试的目的是什么?2个线程是否真的可以同时访问同一个关键部分?
两个线程不能同时访问同一个关键部分; 根据定义,关键部分是互斥的.
要回答您的问题,第一个null测试是没有同步的廉价测试,第二个null测试是通过同步检查实际状态.
第二次测试是必要的.假设我们没有它,代码看起来像这样:
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
helper = new Helper();
}
}
return helper;
}
Run Code Online (Sandbox Code Playgroud)
假设线程A执行if (helper == null)并进行测试true,因此它进入if块但执行被暂停.没有变量更新.
然后线程B执行if (helper == null)并进行测试true,因此它进入if块.然后它继续执行到synchronized块中并初始化helper对象并返回.
现在,线程A继续执行,进入synchronized块,helper用新对象覆盖,然后返回对象.
我们遇到的问题是helper使用不同的对象进行了两次初始化.
这就是为什么第二次测试是必要的.