2013-08-03 34 views
1

使用下面的代码之前完成:的Java自动等待线程启动一个新的

package myapp; 

class Runner extends Thread { 
    public void run(){ 
     for(int i = 0; i < 11; i++){ 
      System.out.println("Hello " + i); 
     } 

     try { 
      Thread.sleep(100); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

public class Class1 { 
    public static void main(String[] args){ 
     Runner t1 = new Runner(); 
     t1.start(); 

     Runner t2 = new Runner(); 
     t2.start(); 
    } 
} 

我得到以下输出:

Hello 0 
Hello 1 
Hello 2 
Hello 3 
Hello 4 
Hello 5 
Hello 6 
Hello 7 
Hello 8 
Hello 9 
Hello 10 
Hello 0 
Hello 1 
Hello 2 
Hello 3 
Hello 4 
Hello 5 
Hello 6 
Hello 7 
Hello 8 
Hello 9 
Hello 10 

而我的输出应该如下:

Hello 0 
Hello 0 
Hello 1 
Hello 1 
Hello 2 
Hello 2 
Hello 3 
Hello 3 
Hello 4 
Hello 4 
Hello 5 
Hello 5 
Hello 6 
Hello 6 
Hello 7 
Hello 7 
Hello 8 
Hello 8 
Hello 9 
Hello 9 
Hello 10 
Hello 10 

怎么回事?我正在使用Eclipse标准版/ SDK版本:开普勒版本
版本ID:20130614-0229,jre7u25和jdk7u25。

+0

你为什么认为应该以第二种方式打印? – Ankit

+0

因为我没有使用join(),并且它是来自示例的确切代码。 – Adam

+0

你的期望是不正确的,输出的顺序被认为是**未定义的**,并且永远不会被指定为任何特定的顺序。 –

回答

4

这是你的问题:

for(int i = 0; i < 11; i++){ 
     System.out.println("Hello " + i); 
    } 

    try { 
     Thread.sleep(100); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

你先通过整个循环运行,然后才睡觉。将中的睡眠移到for循环中,看看会发生什么。

+0

这就是我一直在寻找的东西。非常感谢你! – Adam

2

第一个输出是正确的,你所期待的也是正确的。概率是百万分之一中的一个。

虽然存在多个线程,但不能让任何特定线程有机会运行。一旦发送到jvm(或者在本机程序为CPU的情况下),它应该运行什么线程。

1日放出来是正确的BCZ,代码是如此之小,线程需要切换之前,甚至,它已经完成了它的任务。这就是为什么产量不被干预。也许你可以尝试更大的迭代次数,比如>10000,这样你就可以理解这个概念。或者你可以尝试运行代码次数。您将(可能)从相同的代码中获得不同的输出。

Ps:保持sleep作为最后的指令,实际上没有效果,因为线程几乎完成了它的生命,而你只是在等待死亡。

1

如果2个线程具有相同的优先级,则执行顺序不保证(运行相同程序的两次可能会产生不同的结果),它取决于托管的操作系统,因为它是其工作调度之间的CPU线程。