Here\'s the deal. I have a hash map containing data I call \"program codes\", it lives in an object, like so:
Class Metadata
{
private HashMap validProgramC
The assignment will work as long as you're not concerned about reading stale values, and as long as you can guarantee that your hashmap is properly populated on initialization. You should at the least create the hashMap with Collections.unmodifiableMap on the Hashmap to guarantee that your readers won't be changing/deleting objects from the map, and to avoid multiple threads stepping on each others toes and invalidating iterators when other threads destroy.
( writer above is right about the volatile, should've seen that)
No, the code example is not safe, because there is no safe publication of any new HashMap instances. Without any synchronization, there is a possibility that a reader thread will see a partially initialized HashMap.
Check out @erickson's explanation under "Reordering" in his answer. Also I can't recommend Brian Goetz's book Java Concurrency in Practice enough!
Whether or not it is okay with you that reader threads might see old (stale) HashMap references, or might even never see a new reference, is beside the point. The worst thing that can happen is that a reader thread might obtain reference to and attempt to access a HashMap instance that is not yet initialized and not ready to be accessed.
I think it's risky. Threading results in all kinds of subtly issues that are a giant pain to debug. You might want to look at FastHashMap, which is intended for read-only threading cases like this.
At the least, I'd also declare validProgramCodes
to be volatile
so that the reference won't get optimized into a register or something.
I think your assumptions are correct. The only thing I would do is set the validProgramCodes
volatile.
private volatile HashMap validProgramCodes;
This way, when you update the "pointer" of validProgramCodes
you guaranty that all threads access the same latest HasMap
"pointer" because they don't rely on local thread cache and go directly to memory.