您的位置:首页 > 其它

深入理解join方法的实现原理

2018-03-07 16:33 831 查看
有一道面试题是:

如何控制多线程的执行顺序;

线程的代码就不贴了。上伪码好了:

main(){
thread1.start();
thread1.join();
thread2.start();
thead2.join();
thread3.start();

}


有几个方法都可以做到,这里主要是套路最简单的使用join方法,如何解决。

首先看join方法的API

这是随手百度的 :

join()等待线程结束。



都是很浅的说了一下,要深入理解还是得看源码:

public final synchronized void josin (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()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}


因为join方法 是一个 synchronized 的同步方法。

举个例子,join是在main方法里被调用了。

然后main方法就持有了 join方法 的 这个锁。

然后join 方法里面调用了 wait方法。

这个过程的目的是让持有这个同步锁的线程进入等待。

那么谁持有了这个同步锁呢?

答案就是main方法,因为main方法调用了join方法。

main方法就持有 synchronized 标记的这个锁,谁持有这个锁谁就等待。

wait()方法只会让持有锁的线程进入等待,而启动线程的 start() 并没有持有锁,所以

strat方法还是会执行,而join方法中的wait方法 使main 方法等待了。

所以main方法就没有获取到CPU资源,

所以main方法中的 thread2 就没有办法获取CPU资源。

然后join方法执行完之后,不用想,JVM底层肯定执行了 notify的操作。

网上copy来的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就是当前线程main线程啊。
lock.notify_all(thread);

thread->clear_pending_exception();
}


notify_all 之后 join方法结束,自然 main方法又获取到cpu资源了,然后thread2又可以取得cpu资源,然后又是这个过程。

大概就是这样了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: