是否可以在一次调用中调用Thread start()和join()?

时间:2013-07-14 14:47:50

标签: java multithreading join

我正在使用Java中的线程,我对join()方法有疑问。 假设我有一个扩展Thread的SampleClass。我在main中实例化一些新线程,但我希望使用join()顺序完成线程的工作。

public static void main(String[] args) {
    for(int i=0; i<5; i++){
        new SampleClass().start();
    }
}

是否可以立即调用join()? ......这样的事情:

new SampleClass().start().join();

还是有其他方法可以使用吗? ......就像这样:

new SampleClass().start();
try{Thread.currentThread().join();}catch(InterruptedException e){...}

非常感谢

6 个答案:

答案 0 :(得分:2)

new SampleClass().start().join(); This is wrong.

你可以通过

实现类似的目标
   SampleClass samClass = new SampleClass();
   samClass.start();
   samClass.join()

上面的代码会产生你想要的效果。

现在您的问题是按顺序运行线程。 在大多数情况下    你不需要线程顺序执行的情况(但是有一些情况)。    好吧如果你必须这样做。

然后你可以这样做

   Thread t1 = ..
   Thread t2 = ..

   t1.start();
   t1.join();
   t2.start(); // t2 will start only when t1 dies
   t2.join(); //  
   t3.start(); // t3 will start only when t2 dies..

但上述方法并不好。因为其他线程要启动,以前的线程      需要死。在实践中我们应该考虑将线程创建为昂贵的操作      并尝试重用

真正的问题通常是这样的,你必须执行任务T1,T2,T3,T4    顺序但在不同的线程T1&amp;&amp; T3必须在一个线程和T2和T4上运行    必须在另一个上运行。    所以这里我们可以使用两个线程而不是4个线程。    Thread1将运行T1,然后Thread2将运行T2,然后Thread1将运行T3,依此类推    即。

Thread1 -> T1
Thread2 -> T2
Thread1 -> T3
Thread2 -> T4

所有任务将按顺序执行,但仅使用2个线程。

您可以解决以下问题

  Thread1 ->run {
    while(canIrun) {
    executeTask(taskQueue1.next());
    notifyThread2();
    waitForThread2Signal();
   }
  }

  Thread2 -.run {
   while(canIrun) {
    waitForThread1Signal();
    executeTask(taskQueue2.next());
    notifyThread1();
   }
  }

可以非常轻松地使用CyclicBarrier实现wait和notify方法。

答案 1 :(得分:1)

  

是否可以立即调用join()?

不,因为start()返回void。你不能用这种方式链接那些方法。您需要在Thread对象上调用join()

答案 2 :(得分:1)

答案 3 :(得分:1)

有什么意义?只需调用run()即可获得相同的效果,而无需开销。

答案 4 :(得分:0)

方法start属于Thread类。这就像这样:

Thread thread = new Thread(someRunnableTask);
//This fails to compile, because start returns NOTHING (void). This variable will not be filled with pointer to our thread object.
Thread ourOriginalThreadPointer = thread.start();
//Hence this variable references to nothing, no method can be called.
ourOriginalThreadPointer.join()

答案 5 :(得分:0)

instanciated线程不需要是匿名的。你可以这样做:

public static void main(String[] args) {
    for(int i=0; i<5; i++){
        SampleClass sc = new SampleClass();
        sc.start();
        try {
            sc.join();
        } catch (InterruptedException e) {
        }
    }
}