一,volatile关键字的可见性
从图中可以看出:
①每个线程都有一个自己的本地内存空间–线程栈空间,线程执行时,先把变量从主内存读取到线程自己的本地内存空间,然后再对该变量进行操作
②对该变量操作完后,在某个时间再把变量刷新回主内存
public class RunThread extends Thread {
private boolean isRunning = true;
public boolean isRunning() {
return isRunning;
}
public void setRunning(boolean isRunning) {
this.isRunning = isRunning;
}
@Override
public void run() {
System.out.println("进入到run方法中了");
while (isRunning == true) {
}
System.out.println("线程执行完成了");
}
}
public class Run {
public static void main(String[] args) {
try {
RunThread thread = new RunThread();
thread.start();
Thread.sleep(1000);
thread.setRunning(false);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
现象:该程序出现死循环,没有出现预期的线程内部读取到isRunning = false,进而程序退出
原因分析:在RunThread线程执行的过程中将isRunning = true读取到线程内部空间中,在主线程中将isRunning修改为false后,线程内部空间中的isRunning无法修改,进而没有达到预期。这种情形,在《Effective JAVA》中,将之称为“活性失败”
解决办法 将private boolean isRunning = true 修改为 private volatile boolean isRunning = true,volatile主要是保证强制线程从主内存中取 volatile修饰的变量
unning = true,volatile主要是保证强制线程从主内存中取 volatile修饰的变量