thread1.join()方法阻塞调用此方法的线程,直到线程thread1完成,此线程再继续。
通常用于在main()主线程内,等待其它线程完成再结束main()主线程
@Test /** * output: * 01234 main end. * 如果注释掉【标记1】: * main end.01234 */ public void test06(){ class Task implements Runnable{ public void run() { for(int i=0;i<5;i++){ System.out.print(i); } } } Thread thread1=new Thread(new Task()); thread1.start(); try { thread1.join(); //标记1 } catch (InterruptedException e) { e.printStackTrace(); } System.out.print(" main end."); }
线程调用thread1.join()时,必须能够拿到线程thread1对象的锁。
@Test /** * output: * 占用线程 TaskA run:0 TaskA run:1 TaskA run:2 TaskA run:3 TaskA run:4 释放线程 TaskA run:5 TaskA run:6 TaskA run:7 TaskA run:8 TaskA run:9 main end. */ public void test07(){ class TaskA implements Runnable{ public void run() { for(int i=0;i<10;i++){ System.out.println("TaskA run:"+i); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } } class TaskB implements Runnable{ Thread thread; public TaskB(Thread thread) { this.thread=thread; } public void run() { synchronized(thread){ try { System.out.println("占用线程"); TimeUnit.SECONDS.sleep(5); System.out.println("释放线程"); } catch (InterruptedException e) { e.printStackTrace(); } } } } Thread t1=new Thread(new TaskA()); Thread t2=new Thread(new TaskB(t1)); t2.start(); t1.start(); try { t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("main end."); }
t2通过synchronized(thread) 获取线程对象t1的锁并TimeUnit.SECONDS.sleep(5)后释放,
再此之前main方法调用t1.join(),因为获得不了t1的对象锁所以阻塞,
当t2释放了t1锁后,main线程join()方法,再等待t1线程执行完成后结束