直接看代码
public class WhileTest {
private boolean flag = true;
public void setFlag(boolean flag) {
this.flag = flag;
}
public void say() {
while(flag) {
}
System.out.println("--------------线程停止------------------------------------");
}
public static void main(String[] args) throws InterruptedException {
final WhileTest wt = new WhileTest();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
wt.say();
}
});
t.start();
Thread.currentThread().sleep(500);
wt.setFlag(false);
}
}
很明显,会出现死循环,因为主线程修改共享变量的值,另一个线程并且读取到修改
常见的解决方案是
flag 加上volatile关键字,强制刷新共享变量的值和主内存的值一致。
但是,如果在while循环体中加上一段输出语句,也能够停止线程,原因在哪里,看下源码
public void say() {
while(flag) {
System.out.println("");
}
System.out.println("--------------线程停止------------------------------------");
}
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
原来是因为,输出语句的内容,有一个同步代码块,进入、离开同步代码块,都会和主内存的共享变量的值保证一致,从而实现了可见性。
其实,如果while循环内,加上Thread.sleep语句,给CPU一段时间,cpu会去同步主内存和工作内存的共享变量的值,也能够停止死循环,不过不推荐这样实现,存在不确定性。