在一些情形下,我们必须等待线程的终止。例如,我们的程序在执行其他的任务时,必须先初始化一些必须的资源。可以使用线程来完成这些初始化任务,等待线程终止,再执行程序的其他任务。
为了达到这个目的,我们使用Thread类的join()方法。当一个线程对象的join()方法被调用时,调用它的线程将被挂起,直到这个线程对象完成它的任务。
package concurrency;
import java.util.Date;
import java.util.concurrent.TimeUnit;
public class DataSourcesLoader implements Runnable {
private int second;
public DataSourcesLoader(int second){
this.second = second;
}
@Override
public void run() {
System.out.printf("Beginning data sources loading: %s\n", new Date());
try {
TimeUnit.SECONDS.sleep(second);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Data sources loading has finished: %s\n", new Date());
}
public static void main(String[] args) {
DataSourcesLoader dsLoader = new DataSourcesLoader(4);
Thread thread1 = new Thread(dsLoader,"DataSourceThread1");
DataSourcesLoader dsLoader2 = new DataSourcesLoader(6);
Thread thread2 = new Thread(dsLoader2,"DataSourceThread2");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Main: Configuration has been loaded: %s\n", new Date());
}
}
thread1线程运行结束,thread2线程也运行结束时,主线程对象才会继续运行并且打印出最终的信息。
java提供了另外两种形式的join()方法:
join(long milliseconds)
join(long millseconds,long nanos)
当一个线程调用其他某个线程的join()方法时,如果使用的是第一种join()方式,那么它不必等到被调用线程运行终止,如果参数指定的毫秒时钟已经到达,它将继续运行。例如,threadA中有这样的代码threadB.join(1000),threadA将挂起运行,直到满足下面两个条件之一:
threadB已经运行完成。
时钟已经过去1000毫秒。
当两个条件中的任何一条成立时,join()方法将返回。第二种join()方法跟第一种相似,只是需要接受毫秒和纳秒两个参数。