【问题标题】:Java thread order of executionJava线程执行顺序
【发布时间】:2016-12-28 06:29:55
【问题描述】:

我有这个java main 方法

public class ThreadJoinExample {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        TestJoinClass t1 = new TestJoinClass("t1");  
        TestJoinClass t2 = new TestJoinClass("t2");  
        TestJoinClass t3 = new TestJoinClass("t3");  
        t1.start();  
        try{  
            t1.join();  
        }catch(Exception e){System.out.println(e);}  
        t2.start(); 
        //thread 3 won't start until thread 2 is complete
        t3.start();  
    }

}

我的线程类是

public class TestJoinClass extends Thread{
    //Constructor to assign a user defined name to the thread
    public TestJoinClass(String name)
    {
        super(name);
    }
    public void run(){  
        for(int i=1;i<=5;i++){  
        try{
            //stop the thread for 1/2 second
            Thread.sleep(500);  
            }
        catch(Exception e){System.out.println(e);}  
        System.out.println(Thread.currentThread().getName()+
                " i = "+i);  
        }  
     }
}

这个程序的输出是

t1 i = 1
t1 i = 2
t1 i = 3
t1 i = 4
t1 i = 5
t3 i = 1
t2 i = 1
t3 i = 2
t2 i = 2
t3 i = 3
t2 i = 3
t3 i = 4
t2 i = 4
t3 i = 5
t2 i = 5

我有一个小问题。我想知道为什么 t3 首先开始运行而不是 t2?在代码中,它显示 t2.start() 先于 t3.start() 执行。输出不应该显示 t2 在 t3 之前先执行吗?谢谢

【问题讨论】:

  • //线程 3 在线程 2 完成之前不会启动 不正确
  • t2 t3 将并行运行,因此结果将是随机的
  • Java Thread Example?的可能重复
  • 线程 t2 和 t3 是异步线程。无法确定谁先完成。
  • 寓意是,在使用线程时,如果您希望事情以特定的顺序发生,您需要添加自己的同步代码,以便您的所有线程可以协调它们的活动。

标签: java


【解决方案1】:

这说明了许多人对 Java 并发理解的一个常见错误。

您的bug 在这里:

//thread 3 won't start until thread 2 is complete

它应该是

//thread 2 and 3 will run in parallel, may start in any order and may also interleave their output

【讨论】:

    【解决方案2】:

    当 java 线程的对象调用它的 start() 方法时,程序准备在单独的线程中执行 run() 方法,并且原始调用线程继续执行。因此,一旦 t2.start(); 被调用,t2 线程就准备执行其 run 方法的代码。

    但不保证 t2 的 run() 中的第一行代码会在执行 t3 的 run() 的第一行代码之前先执行,尽管 t2.start( ) 在代码中的 t3.start() 之前调用。因此,对于不同机器/不同运行等上的当前代码,您可能会获得 t2 和 t3 的不同执行顺序和输出。

    所以,总结是完全由 VM 来选择两个并行执行的 run() 方法之间的哪一行代码首先执行。

    【讨论】:

      最近更新 更多