Java中Thread类的join方法到底是如何实现等待
2017-11-25 22:56 faunjoe88 阅读(392) 评论(0) 编辑 收藏 举报现在的场景是A线程执行:
public void run(){
bThread.join(0);//把b线程加入到当前线程(a线程),等待b结束,当前a线程才会结束.
}
B线程执行
public void run(){
for(int i=0;i<10000;i++)
lipMyAss();//亲我的屁股,哦~~亲
}
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源码。