两个线程间变量可见性问题,求大神解答

public class RunThread extends Thread{

private  boolean isRunning = true;
private void setRunning(boolean isRunning){
    this.isRunning = isRunning;
}

public void run(){
    System.out.println("进入run方法..");
    while(isRunning == true){
    }
    System.out.println("线程停止");
}

public static void main(String[] args) throws InterruptedException {
    RunThread rt = new RunThread();
    rt.start();
    Thread.sleep(1000);
    rt.setRunning(false);
    System.out.println("isRunning的值已经被设置了false");
}

}


public class RunThread {

private  boolean isRunning = true;
private void setRunning(boolean isRunning){
    this.isRunning = isRunning;
}
public void run1(){
    while(isRunning == true){
    }
}
public static void main(String[] args) throws InterruptedException {
    final RunThread rt = new RunThread();
    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            rt.run1();
        }
    });
    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            rt.setRunning(false);
        }
    });
    t.start();
    t2.start();
}

}

以上两个程序,对于isRunning变量的线程间可见性,是不一样的,上面的程序不可见,需要加volatile关键字,下面的程序却不需要volatile关键字即可见,这是为什么...

两个程序中的isRunning变量对线程一样,线程间变量都不保证可见性。你的第一个程序中在两个线程间使用Thread.sleep(1000)让主线程休眠了1s,第二个程序为什么没有,保持测试程序的一致性,效果是相同的。

volatile在多处理器开发中保证了共享变量的可见性。
在你下面一段程序中,t2线程调用rt.setRunning(false)后就结束了。如果t2和t线程在同一CPU就一切ok,如果不在同一CPU,线程结束,则会“强制前当前处理器缓存行的数据会写回到系统内存,引起在其他CPU里缓存了该内存地址的数据无效”与volatile做了相同的事情。

可参考文章:深入分析Volatile的实现原理