为什么代码中线程VolatileExample 不会终止
package thread;
public class VolatileExample extends Thread{
private static boolean flag = false;
@Override
public void run() {
while (!flag) {
//System.out.println(1);
}
}
public static void main(String[] args) throws InterruptedException {
VolatileExample v = new VolatileExample();
v.start();
Thread.sleep(1000);
flag = true;
}
}
而
package thread;
public class VolatileExample extends Thread{
private static boolean flag = false;
@Override
public void run() {
while (!flag) {
System.out.println(1);
}
}
public static void main(String[] args) throws InterruptedException {
VolatileExample v = new VolatileExample();
v.start();
Thread.sleep(1000);
flag = true;
}
}
却可以正常终止。
还有这样
package thread;
public class VolatileExample extends Thread{
private static volatile boolean flag = false;
@Override
public void run() {
while (!flag) {
//System.out.println(1);
}
}
public static void main(String[] args) throws InterruptedException {
VolatileExample v = new VolatileExample();
v.start();
Thread.sleep(1000);
flag = true;
}
}
线程也可以正常终止。。。求大神指导。。
while(!flag) 是一个死循环这毋庸置疑了。
第二个类,容易理解吧,执行System.out.println,CPU有机会在时间分片间隙,及时获得flag的值,使循环退出;
第一个类,表面上看起来每次都死锁,但实际上是while{}中间没有任何指令被执行,那么他的时间分片很紧密,很难释放CPU。我理解,不是必然死锁,而是释放的几率比较低,估计试验个∞次可能出现一次能够释放。
至于volatile,文档里这么说:当一个变量被定义为volatile之后,就可以保证此变量对所有线程的可见性,即当一个线程修改了此变量的值的时候,变量新的值对于其他线程来说是可以立即得知的。可以理解成:对volatile变量所有的写操作都能立刻被其他线程得知。
就是说,一旦主线程修改了这个变量的值,run方法能够及时知道,便于退出。