java demo代码可见 https://github.com/sarafina527/JavaPuzzle
package concurrency;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* volatile 保证读写线程的
*/
public class VolatileExample implements Runnable{
int x = 0;
// volatile 变量规则
volatile boolean v = false;
public void writer() {
/**
* 规则1:程序顺序 防止编译优化(volatile)
* 一个线程中,按照程序顺序,前面的操作 Happens-Before后续操作
* 比如此处同一个线程执行过程中 x的赋值永远 先于 v的赋值
* x = 42 << v=true
*/
x = 42;
System.out.println(Thread.currentThread().getName()+" wx :" + x);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
v = true;
System.out.println(Thread.currentThread().getName()+" wv :" + v);
}
public void reader() {
System.out.println(Thread.currentThread().getName()+" rv :" + v);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
/**
* 规则2 :volatile 变量规则 (保证可见行)
* 对一个 volatile 变量的写操作, Happens-Before 后续 对该变量的读操作
* v=true << v==true
* 如此处 run()中先writer()后read() ,所以即使读线程,读v永远在写线程的写v后面执行
*/
if (v == true) {
/**
* 规则3 :传递性
* x=42 << v=true;v=true << v == ture => x=42 << v==true
* 所以此处的x一定时42 ,读线程对写线程x修改 可见
*/
System.out.println(Thread.currentThread().getName()+" rv :" + v);
System.out.println(Thread.currentThread().getName()+" rx :" + x);
}
}
public void run() {
writer();
reader();
}
public static void main(String[] args) {
Executor executor = Executors.newFixedThreadPool(2);
VolatileExample task = new VolatileExample();
// 分别启动读线程和写线程 程序正确性 :保证读线程取x时永远应是42,而非0
executor.execute(task.new WriteTask());
executor.execute(task.new ReadTask());
}
class WriteTask implements Runnable {
public void run() {
writer();
}
}
class ReadTask implements Runnable {
public void run() {
reader();
}
}
}
执行结果