Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.1k views
in Technique[技术] by (71.8m points)

为什么线程一可以读到线程二的非volatile值?请大佬指教。

public static volatile int i = 0;
public static volatile int j = 0;
private static boolean aa = false;
/**
 * 可见性 * * @param args
 * @throws InterruptedException
 */
public static void main(String[] args) throws InterruptedException {

    //线程一
    new Thread(() -> {
 System.out.println("thread 1 run.....");
 while (!aa) {
 int b = i;
 } System.out.println("thread 1 end.....");
 }).start();
 
    TimeUnit.SECONDS.sleep(2);
    //线程二
    new Thread(() -> {
 aa = true;
 System.out.println("更新aa为true");
 try {
 TimeUnit.SECONDS.sleep(5);
 } catch (InterruptedException e) {
 } }).start();
}
//结果,线程二更新完aa变量,线程一跳出了循环。

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

image.png

循环读取volatile 变量 对volatile修饰的变量每次都会从主内存读取
主要是因为 i aa 在同一个缓存行中 每次读取都会附带更新aa
所以 等线程二 更新aa 这个不会立即刷新 主要是后面的println()语句中加锁了 会强制刷新该线程

public void println(boolean x) {
    synchronized (this) { //这里会刷新当前线程工作空间 aa就写到主内存中 然后就读取跳出
        print(x);
 newLine();
 }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
...