Java中Thread类的join方法到底是如何实现等待
现在的场景是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方法到底是如何实现等待的更多相关文章
- Thread类的join()方法
public class Demo { /** * Thread类的join()方法 * -------------------------------- * 1)join() * 2)join(lo ...
- 多线程:Thread类的Join()方法
多线程:Thread类的Join()方法 http://blog.163.com/hc_ranxu/blog/static/3672318220095284513678/ 当我们在线程B中调用Thre ...
- Java中Pattern类的quote方法将任何字符串(包括正则表达式)都转换成字符串常量,不具有任何匹配功能
Java中Pattern类的quote方法将任何字符串(包括正则表达式)都转换成字符串常量,不具有任何匹配功能. 下面是个例子: import org.junit.Test; import java. ...
- Java中Thread类的start()和run()的区别
1.start()方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码. 通 过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪 ...
- java中Thread类分析
创建线程的方式有三种,一是创建Thread实例,二是实现Runnable接口,三是实现Callable接口,Runnable接口和Callable接口的区别是一个无返回值,一个有返回值:不管是Runn ...
- Java中String类的format方法使用总结
可参考: http://www.cnblogs.com/fsjohnhuang/p/4094777.html http://kgd1120.iteye.com/blog/1293633 String类 ...
- Java中Object类的公有方法
HashCode();wait();notify();equals();getClass();toString();clone();finalize(); 这里只是简单介绍一下其中的几个函数: Has ...
- 关于Java中String类的hashCode方法
首先来看一下String中hashCode方法的实现源码 public int hashCode() { int h = hash; if (h == 0 && value.lengt ...
- 【java基础】Thread类之join方法
随机推荐
- GreenPlum 大数据平台--web监控
一,安装web监控界面 01,准备 下载greenplum cc包,>> 解压缩 02,安装前配置 vim /greenplum/data/master/gpseg-/pg_hba.con ...
- Angular4+NodeJs+MySQL 入门-04 接口调用类
上一篇文章说一下,后台接口的创建,这篇说一下如果调用接口. 创建一个目录helpers 此目录下有三个文件分别是 ApiClient.ts.clientMiddleware.ts.Core.ts,前面 ...
- Python-2.7 配置 tab 自动补全功能
作者博文地址:http://www.cnblogs.com/liu-shuai/ 之前一直使用shell编程,习惯了shell的 tab 自动补全功能,而Python的命令行却不支持 tab 自动补全 ...
- 用 Python 构建 web 应用
用 Python 构建 web 应用 如果说仅仅要用 Python 构建 web 应用,可以将 socket 连接.HTTP 原始请求和响应格式等涉及网络基础的东西交给现成的库来实现,只需要专注于 w ...
- SQL脚本整理系列 三
触发器 SQL 2008 怎么实现删除学生表里面的一条记录,成绩表里面关于这个学生的记录也同时删掉,谢求具体代码 --创建表 DROP TABLE tstudent GO CREATE TABLE t ...
- SpringMVC框架下实现分页功能
1.创建实体类Page.java @Entity public class Page { private int totalRecord;// 表示查询后一共得到多少条结果记录 private int ...
- Android-视图绘制
http://blog.csdn.net/guolin_blog/article/details/16330267 任何一个视图都不可能凭空突然出现在屏幕上,它们都是要经过非常科学的绘制流程后才能显示 ...
- 深入Java字符串
深入Java字符串 Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,很多时候,我们对它既熟悉又陌生. 一.从根本上认识java.lang ...
- oracle之数据同步:Oracle Sql Loader使用说明(大批量快速插入数据库记录)
1.准备表数据 select * from emp10; create sequence seq_eseq increment start maxvalue ; --得到序列的SQL语句 select ...
- rest-framework框架——视图三部曲
一.mixins类编写视图 1.配置url urlpatterns = [ ... re_path(r'^authors/$', views.AuthorView.as_view(), name=&q ...