现在的场景是A线程执行:
public void run(){
bThread.join(0);//把b线程加入到当前线程(a线程),等待b结束,当前a线程才会结束.
}
B线程执行
public void run(){
for(int i=0;i<10000;i++)
lipMyAss();//亲我的屁股,哦~~亲
}

看join代码:

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) {//这个分支是无限期等待直到b线程结束
while (isAlive()) {
wait(0);
}
} else {//这个分支是等待固定时间,如果b没结束,那么就不等待了。。。
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}

然后只说无限期等待的情况:

while (isAlive()) {
//只要线程还活着,我tm就等到天荒地老
wait(0);//wati操作,那必然有synchronized与之对应
}

再来看sychronized是谁

public final synchronized void join(long millis)

成员方法加了synchronized说明是synchronized(this)......

this是谁啊?看吧 bThread.join(0); 那说明this就是b线程对象本身。

我擦了个擦,a线程要骂了,tm在我身体里等b线程。

大家都知道,有了wait,必然有notify,我刚保证楼主在整个jdk里面都不会找到对b线程对象的notify操作。这就要看jvm代码了:

//一个c++函数:
void JavaThread::exit(bool destroy_vm, ExitType exit_type) ; //这家伙是啥,就是一个线程执行完毕之后,jvm会做的事,做清理啊收尾工作,
//里面有一个贼不起眼的一行代码,眼神不好还看不到的呢,就是这个: ensure_join(this); //翻译成中文叫 确保_join(这个);代码如下: static void ensure_join(JavaThread* thread) {
Handle threadObj(thread, thread->threadObj()); ObjectLocker lock(threadObj, thread); thread->clear_pending_exception(); java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED); java_lang_Thread::set_thread(threadObj(), NULL); //同志们看到了没,别的不用看,就看这一句,妈了个淡淡,
//thread就是当前线程,是啥是啥?就是刚才说的b线程啊。
lock.notify_all(thread); thread->clear_pending_exception();
}

至此,b线程对象被notifyall了,那么a线程也就能继续跑下去了。

至于wait/notify是怎么实现的,其实jvm实现的方法和java里面的ReentrantLock原理差不多,都是各种waitinglist,各种status判断,各种cas操作,有兴趣可以看ReentrantLock源码。

Java中Thread类的join方法到底是如何实现等待的更多相关文章

  1. Thread类的join()方法

    public class Demo { /** * Thread类的join()方法 * -------------------------------- * 1)join() * 2)join(lo ...

  2. 多线程:Thread类的Join()方法

    多线程:Thread类的Join()方法 http://blog.163.com/hc_ranxu/blog/static/3672318220095284513678/ 当我们在线程B中调用Thre ...

  3. Java中Pattern类的quote方法将任何字符串(包括正则表达式)都转换成字符串常量,不具有任何匹配功能

    Java中Pattern类的quote方法将任何字符串(包括正则表达式)都转换成字符串常量,不具有任何匹配功能. 下面是个例子: import org.junit.Test; import java. ...

  4. Java中Thread类的start()和run()的区别

    1.start()方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码. 通 过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪 ...

  5. java中Thread类分析

    创建线程的方式有三种,一是创建Thread实例,二是实现Runnable接口,三是实现Callable接口,Runnable接口和Callable接口的区别是一个无返回值,一个有返回值:不管是Runn ...

  6. Java中String类的format方法使用总结

    可参考: http://www.cnblogs.com/fsjohnhuang/p/4094777.html http://kgd1120.iteye.com/blog/1293633 String类 ...

  7. Java中Object类的公有方法

    HashCode();wait();notify();equals();getClass();toString();clone();finalize(); 这里只是简单介绍一下其中的几个函数: Has ...

  8. 关于Java中String类的hashCode方法

    首先来看一下String中hashCode方法的实现源码 public int hashCode() { int h = hash; if (h == 0 && value.lengt ...

  9. 【java基础】Thread类之join方法

随机推荐

  1. es6 vs commonjs

    'use strict' export function showMe() { alert("es6"); }; class logging { constructor() { a ...

  2. (转) Linux Shell经典实例解析

    原文:http://blog.csdn.net/yonggeit/article/details/72779955 该篇博客作为对之前Linux Shell常用技巧和高级技巧系列博客的总结,将以Ora ...

  3. 安装wine

    sudo add-apt-repository ppa:ubuntu-wine/ppa sudo apt-get update sudo apt-get install  winetricks

  4. 如何在DIV内只要垂直滚动条,不要水平滚动条

    <DIV style="OVERFLOW-Y: scroll; OVERFLOW-X:hidden; width: 685px; height: 180px">< ...

  5. 理解Windows注册表

    理解Windows注册表 注意 完之前先备份reg 前言 在Windows 3.x之前, Windows都是使用.ini文件来保存配置信息的, 但是.ini文件的大小最大只能为64KB, 为了突破这个 ...

  6. nyoj 1208——水题系列——————【dp】

    水题系列 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述     给你一个有向图,每条边都有一定的权值,现在让你从图中的任意一点出发,每次走的边的权值必须必上一次的权 ...

  7. ubuntu中mysql5.7表名区分大小写解决方案

    在/etc/mysql/mysql.conf.d/mysqld.cnf 添加lower_case_table_names=1

  8. SqlServer系统表认识和操作

    地址:http://technet.microsoft.com/zh-cn/library/ms178551.aspx 一.sys.sysindexkeys 包含有关数据库的索引中的键或列的信息.(表 ...

  9. plsql 连接 虚拟机Linux下的Oracle数据库 失败

    plsql 连接 虚拟机Linux下的Oracle数据库 失败2017年09月09日 09:10:23 守望dfdfdf 阅读数:187 标签: oraclelinux 更多个人分类: 工具 软件编辑 ...

  10. synchronized修饰普通方法和静态方法

    首先,要知道,synchronized关键字修饰普通方法时,获得的锁是对象锁,也就是this.而修饰静态方法时,锁是类锁,也就是类名.class. synchronized修饰普通方法 Synchro ...