Double-checked locking
http://en.wikipedia.org/wiki/Double-checked_locking
<<
>>
http://en.wikipedia.org/wiki/Double-checked_locking
<<
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Single-threaded version | |
public class DoubleCheckedLocking { | |
private Helper helper; | |
public Helper getHelper() { | |
if (helper == null) { | |
helper = new Helper(); | |
} | |
return helper; | |
} | |
// other functions and members... | |
} | |
// Correct but possibly expensive multithreaded version | |
class DoubleCheckedLocking1 { | |
private Helper helper; | |
public synchronized Helper getHelper() { | |
if (helper == null) { | |
helper = new Helper(); | |
} | |
return helper; | |
} | |
// other functions and members... | |
} | |
// Broken multithreaded version | |
// "Double-Checked Locking" idiom | |
class DoubleCheckedLocking2 { | |
private Helper helper; | |
public Helper getHelper() { | |
if (helper == null) { | |
synchronized(this) { | |
if (helper == null) { | |
helper = new Helper(); | |
} | |
} | |
} | |
return helper; | |
} | |
// other functions and members... | |
} | |
// Works with acquire/release semantics for volatile | |
// Broken under Java 1.4 and earlier semantics for volatile | |
class DoubleCheckedLocking3 { | |
private volatile Helper helper; | |
public Helper getHelper() { | |
Helper result = helper; | |
if (result == null) { | |
synchronized(this) { | |
result = helper; | |
if (result == null) { | |
helper = result = new Helper(); | |
} | |
} | |
} | |
return result; | |
} | |
// other functions and members... | |
} | |
// Semantics of final field in Java 5 can be employed to safely publish the helper object without using volatile | |
public class FinalWrapper<T> { | |
public final T value; | |
public FinalWrapper(T value) { | |
this.value = value; | |
} | |
} | |
public class DoubleCheckedLocking4 { | |
private FinalWrapper<Helper> helperWrapper; | |
public Helper getHelper() { | |
FinalWrapper<Helper> wrapper = helperWrapper; | |
if (wrapper == null) { | |
synchronized(this) { | |
if (helperWrapper == null) { | |
helperWrapper = new FinalWrapper<Helper>(new Helper()); | |
} | |
wrapper = helperWrapper; | |
} | |
} | |
return wrapper.value; | |
} | |
} |
>>
Комментариев нет:
Отправить комментарий