I used to believe that any variable that is shared between two threads, can be cached thread-locally and should be declared as volatile. But that belief has been challenged recently by a teammate. We are trying to figure out whether volatile is required in the following case or not.
Worker worker = new Worker();
System.out.println(worker.value); // want to poll value at this instant
class Worker extends Thread
int value = 0; // Should this be declared as a volatile?
public void run()
value = 1; // this is the only piece of code that updates value
Now my contention is that, it is possible that the Worker (child) thread could have cached the variable "value" of the Worker object thread-locally and updated just it's copy while setting the value to 1. In such a case, main thread may not see the updated value.
You are correct. Even though you are both dealing with the same
Worker instance, there is no guarantee that the cached memory version of the
Worker's fields have been synchronized between the various different thread memory caches.
value field must be marked as
volatile to guarantee that other threads will see the
value = 1; update to the
But my teammate believes that since the access to "value" is happening through an object (worker), therefore for both the threads to see different values, it could only be possible if both the threads were maintaining separate copies of "worker" object itself...
No, this is not correct. The tricky part about thread memory revolves around processor memory caches. Without a memory barrier that is imposed by
volatile, a process is completely free to cache memory. So even though both threads would be working with the same instance of the
Worker, they may have a locally cached copy of the memory associated with
Thread architectures get much of their speed because they are working with separate high-speed processor-local memory as opposed to always referencing central storage.