java多线程中join这个方法相信大家都听说过。join这个方法的主要作用就是当前线程等待子线程运行结束。下面是一个join的小示例
public class ThreadJoin {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
IntStream.range(1, 1000)
.forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
});
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
IntStream.range(1, 1000)
.forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
}
}
以上代码,当不进行t1.join的时候,t1x线程会和main线程交替输出,当进行t1.join的时候,main线程会先等t1线程执行完以后再执行输出i循环的代码。再看以下代码
public class ThreadJoin {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
IntStream.range(1, 1000)
.forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
});
Thread t2 = new Thread(()->{
IntStream.range(1, 1000)
.forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("all of tasks finish done");
IntStream.range(1, 1000)
.forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
}
}
以上代码会t1和t2同时执行,等待t1和t2线程都执行结束之后再进行main线程的执行。接着往下看
public class ThreadJoin {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
try {
System.out.println("t1 is running");
Thread.sleep(10_000);
System.out.println("t1 is done");
} catch (Exception e) {
e.printStackTrace();
}
});
t1.start();
try {
t1.join(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("all of tasks finish done");
IntStream.range(1, 100)
.forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
}
}
此处t1.join(100)当t1线程执行超过100毫秒之后main不再等待t1线程执行。
下面举一个join的实例,一个a应用要开启三个线程去采集数据,三个线程分别需要10s,15s,30s,计算最终花费的时间。
public class ThreadJoin {
public static void main(String[] args) throws InterruptedException {
long startTimestamp = System.currentTimeMillis();
Thread t1 = new Thread(new CaptureRunnable("M1",10000L));
Thread t2 = new Thread(new CaptureRunnable("M2",30000L));
Thread t3 = new Thread(new CaptureRunnable("M3",15000L));
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
long endTimestamp = System.currentTimeMillis();
System.out.printf("save data begin timestamp is:%s, end timestamp is%s", startTimestamp, endTimestamp);
}
}
class CaptureRunnable implements Runnable{
private String machineName;
private long spendTime;
public CaptureRunnable(String machineName, long spendTime) {
this.machineName= machineName;
this.spendTime = spendTime;
}
@Override
public void run() {
try {
Thread.sleep(spendTime);
System.out.println(machineName + "completed data capture and success");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String getResult() {
return machineName + " finish.";
}
}
此时如果不给三个线程加上join则三个线程还未采集完数据,主线程就输出花费时间。这么显然不准确,因此给三个线程进行join,这样子就会等三个线程都完成采集数据之后再进行花费时间的计算。