Volatility of objects other than class variables

I used to believe that any variable that is shared between two threads can be cached thread-locally and should be declared mutable. But this belief has recently been challenged by a teammate. We are trying to find out if volatile is required in the following case or not.

class Class1 { void Method1() { Worker worker = new Worker(); worker.start(); ... 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 I argue that it is possible that the Worker (child) stream could cache the variable "value" of the Worker object in the stream and only update it when copying when setting the value 1. In this case, the main stream may not see the updated value.

But my teammate believes that since access to the "value" occurs through the object (worker), therefore for both threads to view different values ​​this is possible only if both threads support separate copies of the "worker" "object itself ( which also means that creating a stream involves creating a deep copy of all common objects).

Now I know that this cannot be true, since for each thread it would be extremely inefficient to maintain completely different copies of all common objects. Therefore, therefore, I seriously doubt it. Does "worker.value" in the main thread reference a different memory location than "this.value" in the child thread? Will the child (worker) cache be “value”?

Sincerely.

+6
source share
2 answers

Now I argue that it is possible that the worker (child) stream could cache the variable "value" of the object "Work object" locally and update by simply copying it when setting the value 1. In this case, the main stream may not see the updated value.

You're right. Although you are working with the same instance of Worker , there is no guarantee that the cached version of Worker field memory is synchronized between different stream stream caches.

The value field must be marked volatile to ensure that other threads will see the value = 1; update value = 1; in the value field.

But my teammate believes that since the “value” is accessed through the object (worker), therefore, for both threads to view different values, this is possible only if both threads support separate copies of the “worker” object itself. ..

No, this is not true. The bulk of thread memory revolves around processor memory caches. Without the volatile memory barrier, the process is completely free to cache memory. Therefore, although both threads will work with the same instance of Worker , they may have a locally cached copy of the memory associated with the Worker .

Stream architectures get most of their speed because they work with separate high-speed processor local memory, and do not always refer to central storage.

+7
source

But my teammate believes that since access to the "value" occurs through the object (worker), therefore for both threads to view different values ​​this is possible only if both threads support separate copies of the "worker" "object itself ( which also means that creating a stream involves creating a deep copy of all common objects).

What your colleague does not understand is that the values ​​of instance variables (any variables in this regard) can be temporarily cached in machine registers or in memory caches of the first or second processor level. The Java language specification explicitly says that two threads will not necessarily see the same values ​​for the same variable if they do not take the appropriate steps.

There is a whole section of JLS that deals with this issue: JLS 17.4 . I recommend that you and your colleague read both 17.5 and 17.6 if you are going to discuss how Java behaves in this area. Or you can read the last chapter of “Java Concurrency in Practice” by Brian Goetz et al., Which is easier to read than JLS.

I would recommend that you and your colleague not rely on their intuition about how threads should work. Read the specifications. Some aspects of the flow behavior are not intuitive ... although there are good reasons, they look the way they are,

+2
source

Source: https://habr.com/ru/post/918205/


All Articles