Consider the following multithreaded code written in Java:
Shared variables:
boolean n; // non-volatile
volatile boolean v; // volatile
Thread 1:
v = true;
System.out.println("n=" + n);
Thread 2:
n = true;
System.out.println("v=" + v);
Assume initially n = v = false
.
Now:
v=false
imply the output of n=true
?n
were volatile?n
were java.util.List
(so that n = true
becomes n.add("something")
and the output n=true
transforms into ["something"]
)?v
were AtomicBoolean
and all reads of and writes to it performed with the compareAndSet
semantic?Could you argue your position according to the Java Memory Model?
UPD: Please treat System.out.println("n=" + n)
as just a read of n
. The same for v
.
UPD2: Could you provide some analysis of the 1st and 4th case as it shown in JSR-133 sec. 8?
There's really three ways that code can execute:
// Thread 1 runs first
T1: v = true;
T1: System.out.println("n=" + n); // prints n=false
// Thread 2 runs second
T2: n = true;
T2: System.out.println("v=" + v); // prints v=true
// They run in parallel, so assignments first, in any order
T1: v = true;
T2: n = true;
// Print statements second, in any order
T1: System.out.println("n=" + n); // may print n=true or n=false (depends on CPU caching)
// will print n=true if n is volatile
T2: System.out.println("v=" + v); // prints v=true
// Thread 2 runs first
T2: n = true;
T2: System.out.println("v=" + v); // prints v=false
// Thread 1 runs second
T1: v = true;
T1: System.out.println("n=" + n); // may print n=true or n=false (depends on CPU caching)
// will print n=true if n is volatile
Does the output of v=false imply the output of n=true?
No. As you can see in 3rd scenario, n
may print either value.
What would change if n were volatile?
As commented, n
will print true
in scenario 2 and 3, instead of being indeterminate.
What would change if n were java.util.List (so that n = true becomes n.add("something") and the output n=true transforms into ["something"])?
This presumes that n
is already a List
before the scenarios start, so the volatility of n
doesn't matter.
Whether the print of n
will see the inserted value depends on the type of list. If the list of not concurrent, the answer is the same as for question 1: It may or may not see the new value. Examples of non-concurrent lists:
set()
, since you cannot call add()
on this kind of list)If the list is concurrent, it will see the new value. Examples of concurrent lists: