join()使用场景
当程序希望各个线程执行完后,将他们的计算结果最终合并运算时,换句话说要等待多个线程将子任务执行完后,才能进行合并结果操作,这时候就可以使用join()。
源码
/** * Waits at most {@code millis} milliseconds for this thread to * die. A timeout of {@code 0} means to wait forever. * * <p> This implementation uses a loop of {@code this.wait} calls * conditioned on {@code this.isAlive}. As a thread terminates the * {@code this.notifyAll} method is invoked. It is recommended that * applications not use {@code wait}, {@code notify}, or * {@code notifyAll} on {@code Thread} instances. * * @param millis * the time to wait in milliseconds * * @throws IllegalArgumentException * if the value of {@code millis} is negative * * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */ public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0;if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }<br /><br /></pre>
有同学疑问,调用join后到底是哪个线程阻塞了?其实很好理解,就是当前执行的线程阻塞,而不是调用join的线程!
public static void main(String[] args) throws InterruptedException { final Thread t = new Thread(new Runnable() { public void run() { try { System.out.println("t线程开始"+System.currentTimeMillis()); Thread.sleep(2000); System.out.println("t线程结束"+System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } });Thread t2 = new Thread(new Runnable() { public void run() { try { t.start(); t.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t2线程结束"+System.currentTimeMillis()); } }); t2.start();</pre>
Thread.currentThread().sleep(1000);
System.out.println(t2.getState());System.out.println("t2线程开始"+System.currentTimeMillis());}</pre>
将上面的测试代码里的join方法,用join的源码替换就一目了然了如下public static void main(String[] args) throws InterruptedException { final Thread t = new Thread(new Runnable() { public void run() { try { System.out.println("t线程开始"+System.currentTimeMillis()); Thread.sleep(2000); System.out.println("t线程结束"+System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } });Thread t2 = new Thread(new Runnable() { public void run() { try { t.start(); //t.join(); //join源码开始 long millis = 0; long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (t.isAlive()) { //wait就是对t2线程的操作 t.wait(0); } } else { while (t.isAlive()) { long delay = millis - now; if (delay <= 0) { break; } t.wait(delay); now = System.currentTimeMillis() - base; } } } catch (InterruptedException e) { e.printStackTrace(); }//join源码结束 System.out.println("t2线程结束"+System.currentTimeMillis()); } }); t2.start(); System.out.println("t2线程开始"+System.currentTimeMillis()); }</pre>
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于