0

我正在使用 Java 中的线程,我对 join() 方法有疑问。假设我有一个扩展 Thread 的 SampleClass。我在主线程中实例化了一些新线程,但我希望线程的工作使用 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){...}

非常感谢

4

6 回答 6

2

重点是什么?只需调用 run()即可获得相同的效果,而无需额外开销。

于 2013-07-14T23:08:04.673 回答
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 && 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 方法。

于 2013-07-15T04:27:15.670 回答
1

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

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

于 2013-07-14T14:48:54.850 回答
1

您可以使用ExecutorService#submit(Runnable runnable).get()

于 2013-07-14T14:50:17.163 回答
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()
于 2013-07-14T14:54:23.973 回答
0

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

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) {
        }
    }
}
于 2013-07-14T22:48:13.637 回答