线程初始化 —— 源码解析
Thread#init()
方法代码片段
Thread parent = currentThread(); |
说明:优先使用线程初始化传入的threadGroup;其次是System SecurityManager的threadGroup;最后才是parent Thread的threadGroup。
g.addUnstarted(); |
说明:NEW状态的线程会添加到threadGroup中,注意,此时还未启动。
this.daemon = parent.isDaemon(); |
说明:新线程的属性依赖于父线程。
/* Set thread ID */ |
说明:加锁,保证线程ID的唯一性。
总结:
一个新构造的线程对象是由其parent线程来进行空间分配的,而child线程继承了parent是否是Daemon、优先级和加载资源的contextClassLoader以及可继承的ThreadLocal,同时还会分配一个唯一的ID来表示这个child线程。至此,一个能够运行的线程对象就初始化好了,在堆内存中等待着运行。
Thread#start()
方法代码片段
private volatile int threadStatus = 0; |
说明:加锁,避免多个线程来同时启动该线程,否则抛出IllegalThreadStateException异常,
try { |
说明:start0()
执行完之前,线程处于READY状态;执行完成后,只要分配了CPU时间片,线程就处于RUNNING状态。这两个状态统称为RUNNABLE状态。
如果start0()
抛出异常了,该异常会直接反馈给调用线程。防止Thread#start
方法感知不到异常,导致程序的错误地继续执行。
总结:
线程对象在初始化完成之后,调用start方法就可以启动该线程。
Thread#start()
方法的含义:当前线程(即parent线程)同步告知JVM,只要线程规划器空闲,应立即启动调用start()方法的线程。
资料:https://www.bilibili.com/video/BV1sw411p7QS/ 强推 河北王校长