深入理解join方法的实现原理
2018-03-07 16:33
831 查看
有一道面试题是:
如何控制多线程的执行顺序;
线程的代码就不贴了。上伪码好了:
有几个方法都可以做到,这里主要是套路最简单的使用join方法,如何解决。
首先看join方法的API
这是随手百度的 :
join()等待线程结束。
都是很浅的说了一下,要深入理解还是得看源码:
因为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代码
notify_all 之后 join方法结束,自然 main方法又获取到cpu资源了,然后thread2又可以取得cpu资源,然后又是这个过程。
大概就是这样了
如何控制多线程的执行顺序;
线程的代码就不贴了。上伪码好了:
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资源,然后又是这个过程。
大概就是这样了
相关文章推荐
- Java Thread&Concurrency(4): 深入理解Exchanger实现原理
- 深入理解.NET程序的原理 谈一谈破解.NET软件的工具和方法
- 【深入理解BufferedInputStream实现原理】
- Java Thread&Concurrency(13): 深入理解ConcurrentLinkedQueue及其实现原理
- 理解Stack、Heap并深入实现ObjC中alloc、retain、release与dealloc方法
- Java Thread&Concurrency(10): 深入理解ThreadLocal及其实现原理
- Java Thread&Concurrency(2): 深入理解ConcurrentSkipListMap实现原理
- Python THREADING模块中的JOIN()方法深入理解
- 深入理解Lua的闭包一:概念、应用和实现原理
- Java Thread&Concurrency(15): 深入理解ScheduledThreadPoolExecutor及其实现原理
- 【Android个人理解(二)】从实现方法深入了解自定义适配器的工作过程
- 深入理解Redis主键失效原理及实现机制(转)
- Python THREADING模块中的JOIN()方法深入理解
- 深入理解PHP原理之--echo的实现
- Java Thread&Concurrency(12): 深入理解AbstractExecutorService及其实现原理
- 深入理解PHP原理之--echo的实现
- Java Thread&Concurrency(5): 深入理解Phaser实现原理
- 2本Hadoop技术内幕电子书百度网盘下载:深入理解MapReduce架构设计与实现原理、深入解析Hadoop Common和HDFS架构设计与实现原理
- 黑马程序员【深入理解BufferedInputStream实现原理】
- 深入理解Redis主键失效原理及实现机制