Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

confuse about java thread variable visibility

All example I found which talk about visibility is example with primitive type. What I want to know is: if a object which new in heap, when one thread call its method to change its state, without locking or synchronize, other thread will see this change? Imagine a Java.Colletion object, one thread call its add() method

Someone says for object in heap still has visibility problem, but the JLS said: 17.4.1 Shared Variables Memory that can be shared between threads is called shared memory or heap memory.

and http://www.artima.com/insidejvm/ed2/jvm2.html said: A thread's Java stack stores the state of Java (not native) method invocations for the thread. The state of a Java method invocation includes its local variables, the parameters with which it was invoked, its return value (if any), and intermediate calculations.

So I think, JVM will not copy a object which in heap to CPU cache. If this is correct, object in heap won't have visibility problem, because thread just reference to the object in heap.

BTW Assume there is concurrent problem when one thread call .add(). In normal process, the change must guard with a lock, so this problem is not a problem. But I just want to know :)

like image 247
jean Avatar asked Jul 19 '11 03:07

jean


2 Answers

The answer is "no, the other thread will not necessarily see the change to the Collection", because (most of) the standard Collections are not thread-safe - that is, they do not have safe publication of their state. (The other thread may, or may not see the change).

That is why the java.util.concurrent package was created - it provides thread-safe implementations of java.util.Collections.

like image 84
Bohemian Avatar answered Sep 23 '22 14:09

Bohemian


You can still perform memory synchronisation without synchronized if you have volatile, atomic variables, or other concurrent containers that provide happens-before semantics. However, if you do none of those things, then nothing is guaranteed with regard to memory visibility.

In your particular case, if you want to call add() on a container in one thread and have it be visible in another without explicit locking, then this will only work if the container is a concurrent one (e.g., one of the ones in the java.util.concurrent package), or a synchronised one (e.g., Collections.synchronizedList).

like image 22
Chris Jester-Young Avatar answered Sep 25 '22 14:09

Chris Jester-Young