这是我的代码:
public class Test {
private static /*volatile*/ int count = 0;
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
while(true){
//System.out.println(1); //①
if(count==10){
System.out.println("I'm over");
break;
}
}
}
}).start();
//run ten thread
for(int i=0;i<10;i++){
new Thread(new Runnable() {
public void run() { System.out.println(Thread.currentThread()+","+Math.random());
count = count+1;
}
}).start();
}
}
当我使用jdk7打印“我结束了”当然线程结束了,但是当我使用jdk8时,线程永远不会到达那里。
看起来总是在等待,当然永远不会打印“我结束了”。 为什么?这是一个jdk BUG吗?
答案 0 :(得分:0)
您的代码不是线程安全的,这意味着未定义程序的语义。这在Java语言规范中指定。在这种情况下,JVM的行为可能会有所不同,具体取决于其版本,您使用的计算机,操作系统或外部天气。它是不 JVM中的错误。
取自https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5:
必须正确同步程序,以避免在重新排序代码时可以观察到的各种违反直觉的行为。使用正确的同步不能确保程序的整体行为是正确的。但是,它的使用确实允许程序员以简单的方式推理程序的可能行为;正确同步的程序的行为更少依赖于可能的重新排序。如果没有正确的同步,很可能会产生非常奇怪,混乱和违反直觉的行为。
答案 1 :(得分:0)
可以在版本之间更改java内存模型。我们必须阅读规格以确定。无论如何,我的猜测是for循环中的行count = count+1;
不是原子的,多个线程会覆盖它并阻止它达到10。