这是一个JDK线程BUG

时间:2017-01-20 08:41:12

标签: java multithreading

这是我的代码:

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吗?

2 个答案:

答案 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。