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的实现原理