join应用
上篇咱们介绍了CountDownLatch,顺便说到了Thread中的join办法!
import java.util.concurrent.TimeUnit;/** * @author :jiaolian * @date :Created in 2021-02-28 21:43 * @description:join测试 * @modified By: * 公众号:叫练 */public class JoinTest { public static void main(String[] args) throws InterruptedException { Thread threadA = new Thread(()->{ try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+":想先执行"); },"线程A"); //开启一个线程A threadA.start(); //主线程会持有子线程的锁,子线程还没开始主线程就阻塞了,期待子线程完结后告诉; threadA.join(); System.out.println(Thread.currentThread().getName()+ "线程执行"); }}
如上代码所示:在JoinTest开启一个线程A,threadA调用join()办法,主线程会期待threadA执行结束!也就是两秒后,主线程执行最初一句话,运行后果如下图所示!
咱们深刻源码,join办法底层其实就是一个wait办法,但当初问题是:明明调用者是线程A,可阻塞的是mian线程,不应该阻塞的是threadA吗?
证实问题:明明调用者是线程A,可阻塞的是mian线程
咱们参照Thread中join源码,将下面的代码革新如下:
import java.util.concurrent.TimeUnit;/** * @author :jiaolian * @date :Created in 2021-02-28 21:43 * @description:join测试 * @modified By: * 公众号:叫练 */public class JoinCodeTest { public static void main(String[] args) throws InterruptedException { MyThread threadA = new MyThread("线程A"); //开启一个线程A threadA.start(); //主线程会持有子线程的锁,子线程还没开始主线程就阻塞了,期待子线程完结后告诉; threadA.join2(0); System.out.println(Thread.currentThread().getName()+ "线程执行"); } private static class MyThread extends Thread { public MyThread(String name) { super(name); } @Override public void run() { try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+":想先执行"); } //复制Thread源码中的join办法测试阻塞的是线程A还是main线程? public final synchronized void join2(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()) { //尽管调用者是线程A,但真正执行阻塞的是main线程! System.out.println(Thread.currentThread().getName()+"会阻塞"); wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } } }}
如上代码所示:MyThread继承Thread,并复制了join源码,将join批改成join2,并在join2办法中减少了一个输入语句,System.out.println(Thread.currentThread().getName()+"会阻塞")用来测试阻塞的是线程A还是main线程,所以在JoinCodeTest的main办法中ThreadA是调用join2办法,
后果发现进入join2办法的线程是main线程。运行后果如下图所示!
这里能够把join了解成一个一般办法!真正阻塞的不是调用者线程,而是以后正在执行的线程。
总结
明天咱们介绍了join办法,特地是将源码中代码copy进去证实测试,置信整理出来心愿能对你有帮忙,写的比不全,同时还有许多须要修改的中央,心愿亲们加以斧正和点评,喜爱的请点赞加关注哦。点关注,不迷路,我是【叫练】公众号,微信号【jiaolian123abc】边叫边练。