static volatile Map currentMap = null; // this must be volatile
static Object lockbox = new Object();
public static void buildNewMap() { // this is called by the producer
Map newMap = new HashMap(); // when the data needs to be updated
synchronized (lockbox) { // this must be synchronized because of the Java memory model
// .. do stuff to put things in newMap
newMap.put(....);
newMap.put(....);
}
/* After the above synchronization block, everything that is in the HashMap is visible outside this thread */
/* Now make the updated set of values available to the consumer threads. As long as this write operation can complete without being interrupted,
and is guaranteed to be written to shared memory, and the consumer can live with the out of date information temporarily, this should work fine */
currentMap = newMap;
}
public static Object getFromCurrentMap(Object key) {
Map m = null;
Object result = null;
m = currentMap; // no locking around this is required
if (m != null) { // should only be null during initialization
Object result = m.get(key); // get on a HashMap is not synchronized
// Do any additional processing needed using the result
}
return(result);
}
Thesynchronized
block and thevolatile
keyword in Listing 1 are required because no happens-before relationship exists between the writes to thecurrentMap
and the reads fromcurrentMap
.
The volatile variable ensures that there is a happens-before edge between the write and the read.
So the synchronized block isn't needed; it even doesn't provide any visibility guarantee because:
- currentMap = newMap is not send in the synchronized block
- currentMap isn't read in the synchronized block.
I'm not completely sure what the purpose is of the synchronized block.
Keep in mind that this article is of 2007. So it is pretty old.
--
You received this message because you are subscribed to the Google Groups "mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mechanical-symp...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/mechanical-sympathy/337d1e27-b31f-4e57-a937-62929fad54a2o%40googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/mechanical-sympathy/CAGuAWdCY1A2ErZJkp7ns7tuyq1UOcUJqA8QyUsrCMS5EzQ5UGA%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mechanical-symp...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/mechanical-sympathy/69a4dd6c-8f15-47b7-936c-17761b481df6o%40googlegroups.com.
MemoizingSupplier is keeping the delegate forever.
NonSerializableMemoizingSupplier is releasing the delegate (delegate = null) when the value is captured because it's not needed anymore.
That's why one is final and the other volatile.
To view this discussion on the web, visit https://groups.google.com/d/msgid/mechanical-sympathy/CADZL2%3DtjuFFn9pPMBApmG8dVZ5CNNNetEXogZ1H9%2BjyuUU9%2B3w%40mail.gmail.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/mechanical-sympathy/CAJ183RNmFDBYA3HqOjrwHHiiQJ-OAbKc1x8YrZ1n9uMYnkSHVg%40mail.gmail.com.