一、概述
与 wait()和notify() 方法一样,join()是另一种线程间同步机制。
当调用join()方法时,调用线程进入等待状态。它一直处于等待状态,直到被调用的线程终止。
二、Thread.join()方法
参考代码
class SampleThread extends Thread {
public int processingCount = 0;
public SampleThread(int processingCount) {
this.processingCount = processingCount;
LOGGER.info("Thread Created");
}
@Override
public void run() {
LOGGER.info("Thread " + this.getName() + " started");
while (processingCount > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
LOGGER.info("Thread " + this.getName() + " interrupted");
}
processingCount--;
}
LOGGER.info("Thread " + this.getName() + " exiting");
}
}
@Test
void test_join()
{
Thread t2 = new SampleThread(1);
t2.start();
System.out.println("Invoking join");
try {
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Returned from join");
System.out.println(t2.isAlive());
}
输出如下
Thread Created Invoking join Thread Thread-2 started Thread Thread-2 exiting Returned from join false
如果引用的线程被中断,join()方法也可能返回。在这种情况下,该方法抛出一个 InterruptedException。
最后,如果引用的线程已经终止或尚未启动,则调用join()方法会立即返回。
三、带超时的Thread.join()方法
如果引用的线程被阻塞或处理时间过长,join() 方法将继续等待。因为调用线程将变得无响应。 为了处理这些情况,我们使用允许我们指定超时时间的 join() 方法的重载版本。
有两个重载 join() 方法的定时版本:
public final void join(long millis) throws InterruptedException
public final void join(long millis,int nanos) throws InterruptedException
测试代码
@Test
public void waitsUntilTimedout()
throws InterruptedException {
Thread t3 = new SampleThread(10);
t3.start();
t3.join(1000);
assertTrue(t3.isAlive());
}
在这种情况下,调用线程等待大约 1 秒以等待线程 t3 完成。如果线程 t3 在此时间段内未完成,则join()方法将控制权返回给调用方法。
Timed join()取决于操作系统的计时。不一定等于我们等待指定的时间。