Java volatile读可见性保障的多线程场景取值问询
First, let's recap the key JVM guarantee you referenced:
当线程A写入一个volatile变量,随后线程B读取同一个变量时,线程A在写入该volatile变量之前可见的所有变量的值,在线程B读取该volatile变量之后都将对B可见。
Let's walk through the execution timeline you provided to figure out what p2.b will print at t=7:
- t=1: Th1 writes
p1.a = 10to its local working memory (main memory still holds the initial valuea=1). - t=2: Th1 writes
p1.b = 10to its local working memory (main memory still hasb=1). - t=3: Th2 writes
p2.a = 30to its local working memory (main memory remainsa=1). - t=4: Th2 writes
p2.b = 30to its local working memory (main memory remainsb=1). - t=5: Th1 writes
p1.c = 10—sincecis volatile, this triggers a critical JMM behavior: all shared variables in Th1's working memory (a=10,b=10,c=10) get flushed to main memory. Now main memory holdsa=10,b=10,c=10. - t=6: Th2 runs
int x = p2.c;(a volatile read). Here's what happens next per JVM rules:- Th2's local working memory is marked invalid for all shared variables.
- Th2 must reload every shared variable from main memory. This overwrites Th2's local values: its working memory now has
a=10,b=10,c=10(replacing thea=30,b=30it had stored earlier).
- t=7: Th2 prints
p2.b. Since its working memory now holds the main memory value10(reloaded at t=6), the output will be 10.
You might be wondering: what about Th2's write of b=30 at t=4? That change was only in Th2's local working memory and never flushed to main memory before the volatile read. When the volatile read forces a refresh from main memory, that unsynchronized local write gets overwritten by the latest valid value from main memory (set by Th1 at t=5).
To tie this to the happens-before relationship (the formal foundation of JVM visibility):
- Th1's writes to
aandb(t=1, t=2) happen-before Th1's write to volatilec(t=5) (per the program order rule: actions in the same thread are ordered by execution order). - Th1's write to
c(t=5) happens-before Th2's read ofc(t=6) (per the volatile variable rule: writes to a volatile variable happen-before all subsequent reads of that variable). - By transitivity, Th1's writes to
aandbhappen-before Th2's read ofb(t=7). This enforces that Th2 sees Th1's values foraandbafter reading the volatilec.
内容的提问来源于stack exchange,提问作者user3724707

