对象共享
package com.git.poan.multithreadpractice;
public class NoVisibility {
private static boolean ready;
private static int number;
public static void main(String[] args) throws InterruptedException {
Thread readThread = new Thread(() -> {
while (!ready) {
Thread.yield();
}
System.out.println(number);
});
readThread.start();// 只是处于就绪状态,理论上会很快就执行run
number = 42; // 这一步是主线程执行,readThread不一定会读取到这个变量,读不到的话就是默认值0
ready = true;// 这一步是主线程执行,readThread也不一定能读取到这个变量;读不到的话就是默认值false
}
}
以上的代码一般执行不会发现问题,执行多次(或者放到for循环执行多次),才能发现书中所说现象:
- 输出0:readThread读取到了主线程将read设为true,但是没读取到number=42
- 停止在yield:readThread没有读取到read为true,导致一直挂起
以上只有两个线程,readThead会读取主线程设置到的number和ready,但是这两个值都是static的,默认值分别是false和0,就会出现这种情况; 并且number=2和ready=true这两句,因为没有happen-before的关系,有可能会发生重拍序的现象。