public class Test extends Thread {
private Boolean stop = false;
public static void main(String[] args) throws Exception {
Test test = new Test();
test.start();
TimeUnit.SECONDS.sleep(1);
test.stop = true;
}
@Override
public void run() {
while (!this.stop) {
}
System.out.println("end");
}
}
这样编写代码,线程将无限执行。但是,在while循环中添加一些内容,并将其更改为如下所示:
public class Test extends Thread {
private Boolean stop = false;
public static void main(String[] args) throws Exception {
Test test = new Test();
test.start();
TimeUnit.SECONDS.sleep(1);
test.stop = true;
}
@Override
public void run() {
while (!this.stop) {
System.out.println(1); // Add some code
}
System.out.println("end");
}
}
为什么会这样? ???为什么我可以通过打印句子来打断它,并且不打印就不会被打断。 。 。 。 。 。 。 。 。 。 。 。 。 。请注意,未添加stop
volatile
。如果添加,则可以在1秒钟后停止。
答案 0 :(得分:2)
因为stop
不是volatile
,所以不能保证一个线程所做的更改会被另一个线程看到(除非其他东西提供了类似锁的保证)。这样您将获得无法预测的结果。
如果一个线程对对象的更改需要在另一个线程中可见,则有大量无法进行的优化。但这仅是很小一部分实际代码的要求。因此,Java实现者明智地决定使依赖于该行为的代码表明这一点,并允许对不关心这一点的99.5%的代码进行这些重要的优化。
如果要依靠一个线程对另一个线程可见的更改,则必须使用指定的一种机制来提供此行为。否则,结果将无法保证。