views:

78

answers:

3

I wonder if when using any of the java.util.concurrent classes I still need to synchronize access on the instance so to avoid visibility issues.

In short the question is:

When using an instance of java.util.concurrent, is it possible that one thread modify the instance (i.e., put an element in a concurrent hashmap) and a subsequent thread won't be seeing the modification? (My question arises from the fact that The Java Memory Model allows threads to cache values instead of fetching them directly from memory if the access to the value is not synchronized)

+1  A: 
Tomas Narros
Not sure that's the "answer", that just demonstrates the spec for syncrhonized. I understood the question to be more about the need to add additional syncrhonisation..?
Toby
You got it right Toby. I wanted to know whether I could assume that by using java.utils.concurrent classes I would not had to worry about visiblity issues, i.e., whether synchronizing is or is not necessary with these classes.
Mirco
Ok. My fault. I misunderstood the question.
Tomas Narros
Brilliant!! Thanks Tomas, the "Memory Consistency Property" was exactly what I needed! I'm happy I can assume that updates made on java.util.concurrent classes are garanteed to be visible.
Mirco
I'm glad to help.
Tomas Narros
+1  A: 

I wonder if when using any of the java.util.concurrent classes I still need to synchronize access on the instance so to avoid visibility issues.

There is no single answer to this. Rather, you need to check the answer on a case-by-case basis, by carefully reading the relevant classes javadocs.

When using an instance of java.util.concurrent, is it possible that one thread modify the instance (i.e., put an element in a concurrent hashmap) and a subsequent thread won't be seeing the modification?

In the case of ConcurrentHashMap, the javadoc says the following about the behaviour of retrieval (read) operations:

"However, even though all operations are thread-safe, retrieval operations do not entail locking, and there is not any support for locking the entire table in a way that prevents all access. [...] Retrievals reflect the results of the most recently completed update operations holding upon their onset."

In other words, "No, it is not possible".

Stephen C
A: 

Because the ConcurrentHashMap (for example) is designed to be used from a concurrent context, you don't need to synchronise it further. In fact, doing so could undermine the optimisations it introduces.

For example, Collections.synchronizedMap(...) represents a way to make a map thread safe, as I understand it, it works essentially by wrapping all the calls within the synchronized keyword. Something like ConcurrentHashMap on the other hand creates synchronized "buckets" across the elements in the collection, causing finer grained concurrency control and therefore giving less lock contention under heavy usage. It may also not lock on reads for example. If you wrap this again with some synchronised access, you could undermine this. Obviously, you have to be careful that all access to the collection is syncrhronised etc which is another advantage of the newer library; you don't have to worry (as much!).

The java.lang.concurrent collections may implement their thread safety via syncrhonised. in which case the language specification guarantees visibility. They may implement things without using locks. I'm not as clear on this, but I assume it the same visibility would be in place here.

If you're seeing what looks like lost updates in your code, it may be that its just a race condition. Something like the ConcurrentHashpMap will give you the most recent value on a read and the write may not have yet been written. It's often a trade off between accuracy and performance.

The point is; java.util.concurrent stuff is meant to do this stuff so I'd be confident that it ensures visibility and use of volatile and/or addition syncrhonisation shouldn't be needed.

Toby