博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
我也学习JAVA多线程-join
阅读量:6893 次
发布时间:2019-06-27

本文共 2233 字,大约阅读时间需要 7 分钟。

在工作中,挺少遇到join关键字,但很多多线程资料和面试过程中,初中级开发工程师总会遇到join。

今天一起学习下join。
join的作用:等待指定的时间(当为0时,一直等待),直到这个线程执行结束。
先看join方法的定义,join是java.lang.Thread的一个普通方法。

package java.lang;// Thread竟然实现了Runnable接口,之前好像注意到过,但是没在意。// 根据构造方法和run()方法可以看出,本质还是执行的Runnable的实现。public class Thread implements Runnable {    …    public final void join() throws InterruptedException {        join(0);    }    …}

演示代码

public class ThreadLearnJoin {    public static void main(String[] args) throws InterruptedException {        Thread t = new Thread(new Runnable() {            @Override            public void run() {                System.out.println(Thread.currentThread().getName() + "睡觉");                try {                    TimeUnit.SECONDS.sleep(5);                } catch (InterruptedException e) {                    e.printStackTrace();                }                System.out.println(Thread.currentThread().getName() + "起床");            }        }, "sub-thread");        t.start();        System.out.println(Thread.currentThread().getName() + "线程join前");        t.join();        System.out.println(Thread.currentThread().getName() + "线程join后");    }}

执行结果

main线程join前sub-thread睡觉sub-thread起床main线程join后

源码分析

继续分析join(0)的代码,首先需要注意的是synchronized关键字,其次是isAlive()和wait(0)。在演示代码中,主线程调用名称为sub-thread的子线程t的join()方法。

主线程先获取t对象上的锁,并且当t为Alive状态时,继续调用t的wait(0)方法。
由于wait()方法是Object的方法,跟子线程t并没有关系,wait()会释放t对象上的锁,并阻塞当前main线程。
这里也就隐藏了一个点:t线程调用start()后,进入执行状态,运行run()方法中的代码,和t对象上的锁并没有任何关系。
run方法并没有进入synchronized的同步区。

public final synchronized void join(long millis) throws InterruptedException {    …    if (millis == 0) {        while (isAlive()) {            wait(0);        }    }    …}

参考资料

  • Java多线程系列--“基础篇”08之 join()
    以下是的评论,可以帮助大家理解记忆。
问题:虽然s.join()被调用的地方是发生在“Father主线程”中,但是s.join()是通过“子线程s”去调用的join()。  那么,join()方法中的isAlive()应该是判断“子线程s”是不是Alive状态;对应的wait(0)也应该是“让子线程s”等待才对。但如果是这样的话,s.join()的作用怎么可能是“让主线程等待,直到子线程s完成为止”呢,应该是让"子线程等待才对(因为调用子线程对象s的wait方法嘛)"?  答案:wait()的作用是让“当前线程”等待,而这里的“当前线程”是指当前在CPU上运行的线程。所以,虽然是调用子线程的wait()方法,但是它是通过“主线程”去调用的;所以,休眠的是主线程,而不是“子线程”!这个这么讲的不清楚吧?调用wait()方法 应该是当前线程持有的对象调用wait() 让线程等,并释放对象锁。在主线程中调用了s.join() join()方法用synchronized修饰了,也就是说当前主线程已经持有了s的锁 这个调用s这个对象wait()方法 让主线程等待并释放s对象锁。

转载于:https://www.cnblogs.com/Candies/p/10635419.html

你可能感兴趣的文章
vim利器:vundle 管理器和NERDTree插件
查看>>
一些链接资源
查看>>
Swift 笔记3
查看>>
手势解锁,就这么简单
查看>>
CSS“隐藏”元素的几种方法的对比
查看>>
Executor执行框架
查看>>
[FMX] Android APP 启动黑屏优化补丁
查看>>
常用JavaScript的高级技巧
查看>>
bzoj 1670: [Usaco2006 Oct]Building the Moat护城河的挖掘
查看>>
摘抄:Java多线程学习
查看>>
mysql 不同索引的区别和适用情况总结
查看>>
Html5使用canvas作图线宽很粗
查看>>
[转]Ubuntu下ROS开发环境搭建(QT+ros_qtc_plugin)
查看>>
iOS. PercentEscape是错用的URLEncode,看看AFN和Facebook吧
查看>>
day01 认识python变量 数据类型 条件if语句
查看>>
【算法学习笔记】38.最短路问题 SJTU OJ 1105 path
查看>>
MarkDown写blog(测试)
查看>>
36.intellij idea 如何一键清除所有断点
查看>>
EasyUI Menu 菜单
查看>>
61.员工信息管理Extjs 页面
查看>>