案例代码
@Slf4j public class JoinDemo { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { log.info("{} 线程启动", Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } log.info("{} 线程执行任务", Thread.currentThread().getName()); }, "t1"); Thread t2 = new Thread(() -> { log.info("{} 线程启动", Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } log.info("{} 线程执行任务", Thread.currentThread().getName()); }, "t2"); t1.start(); t2.start(); log.info("{} 线程执行任务", Thread.currentThread().getName()); } }
从上面的结果可以看出,main 线程首先获取到了 CPU 的时间片,然后执行,接着 t2 和 t1 获取到 CPU 时间片,获得执行
如果我们想 main 线程在 t1 和 t2 线程执行完任务之后再去执行 main 线程的任务,那该怎么办呢,这个时候就可以使用线程类提供的 join 方法了
@Slf4j public class JoinDemo { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { log.info("{} 线程启动", Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } log.info("{} 线程执行任务", Thread.currentThread().getName()); }, "t1"); Thread t2 = new Thread(() -> { log.info("{} 线程启动", Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } log.info("{} 线程执行任务", Thread.currentThread().getName()); }, "t2"); t1.start(); t2.start(); // 在主线程中分别调用 t1、t2 线程的 join() 方法,那么主线程就会等待 t1 和 t2 线程执行完毕之后再去执行主线程自身的任务 t1.join(); t2.join(); log.info("{} 线程执行任务", Thread.currentThread().getName()); } }
使用 join 方法之后,main 线程会等待 t1、t2 线程执行完成自身的任务之后,接着才会去执行 main 线程的任务
上面我们使用的是 join() 的无参方法,无参的 join 方法实际上就是等价于 join(0)
接着我们看一下这个有参的 join 方法
如果传递进来的参数大于 0,底层实际上是调用 wait(delay),这个方法的作用是只会做有时限的等待,过时不候
@Slf4j public class JoinDemo { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { log.info("{} 线程启动", Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } log.info("{} 线程执行任务", Thread.currentThread().getName()); }, "t1"); t1.start(); // 只会做有时限的等待,如果等待的时间超过了 t1 线程的执行时间,那么就不再继续等待了 t1.join(2000); log.info("{} 线程执行任务", Thread.currentThread().getName()); } }
从执行结果中可以看出,main 线程只等待了 2000ms,然后就开始执行 main 线程的任务去了,此时 t1 线程还没有执行完毕,main 线程就停止了等待
标签:join,currentThread,Thread,getName,t1,线程,方法,log From: https://www.cnblogs.com/xiaomaomao/p/17956867