Say you have this code:
private String cachedToken;
private final Object lockObject = new Object();
....
retrieveToken(){
synchronized(lockObject){
if (cachedToken == null){
cachedToken = goGetNewToken();
}
return cachedToken;
}
}
Will the write to cachedToken
be visible to all threads that have locked on lockObject
?
Yes. Synchronizing on lockObject establishes a Happens Before Relationship (aka sets up a memory barrier). This means that all threads that subsequently get the lock will see any changes that happened while the lock was held previously.
For what it's worth, though, your implementation of lazy initialization is flawed. This is the proper way:
private volatile String cachedToken;
retrieveToken() {
if (cachedToken == null) {
synchronized(lockObject) {
if (cachedToken == null) {
cachedToken = goGetNewToken();
}
}
}
return cachedToken
}
This way you only have to get the lock a small handful of times when Threads first start requesting it. After that the cachedToken will not be null, and you won't need to synchronize.
Of course, synchronize
ensure two things:
Whereas for instance, volatile
ensure memory barrier but doesn't handle atomicity.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.