@@ -10,21 +10,28 @@ public class Thread implements Runnable {
1010 private int priority;
1111 /* * 是否为守护线程 */
1212 private boolean daemon;
13- /* * 目标任务 */
13+ /* * 线程要执行的目标任务 */
1414 private Runnable target;
1515 /* * 所属线程组 */
1616 private ThreadGroup group;
1717 /* * 类加载器 */
1818 private ClassLoader contextClassLoader;
1919 /**
20- * ThreadLocal设置线程私有变量时 就是通过下面这两个参数完成的,
21- * ThreadLocal的get/set方法就是通过操作 各个线程的 threadLocals 变量实现的
20+ * ThreadLocal 能为线程设置线程私有变量 就是通过下面这个threadLocals变量完成的,
21+ * ThreadLocal的get/set方法就是通过操作 各个线程的 threadLocals 变量实现的。
22+ * 1、线程A持有一个 ThreadLocalMap 变量;
23+ * 2、线程A调用一个类的 ThreadLocal变量 tlA 的 get/set方法;
24+ * 3、tlA(ThreadLocal)的 get/set方法 获取当前线程A,调用 线程A 的 ThreadLocalMap变量 的get/put方法;
25+ * 4、其它线程 调用 tlA(ThreadLocal)的 get/set方法 同理。
2226 */
2327 ThreadLocal . ThreadLocalMap threadLocals;
2428 ThreadLocal . ThreadLocalMap inheritableThreadLocals;
2529 /* * 线程栈的大小 */
2630 private long stackSize;
27- /* * 线程状态:新建、就绪/运行、阻塞、等待、销毁 */
31+ /**
32+ * Thread类定义了6个线程状态:New、Runnable、Blocked、Waiting、TimedWaiting、Terminated(终止)
33+ * 实际上还会把 Runnable 再细分为 就绪(未抢到时间片) 和 运行中(抢到时间片)
34+ */
2835 private volatile int threadStatus;
2936 /* * 最小优先级 */
3037 public static final int MIN_PRIORITY = 1 ;
@@ -39,7 +46,7 @@ public class Thread implements Runnable {
3946 * RUNNABLE: 运行,在java多线程模型中,就绪和运行都是运行状态;
4047 * BLOCKED: 阻塞;
4148 * WAITING: 等待,需要其他的线程来唤醒;
42- * TIMED_WAITING:超时等待,可以在指定的时间内自动醒来;
49+ * TIMED_WAITING:超时等待,可以在指定的时间内自动醒来,如 sleep()方法 ;
4350 * TERMINATED: 终止,线程执行完毕。
4451 */
4552 public static final class State extends Enum {
@@ -69,8 +76,8 @@ public class Thread implements Runnable {
6976
7077 /**
7178 * 一系列 构造方法 ------------------------------------------------------
72- * 可以看出来,其中都调用了init()方法,这也是一个约定俗成的规矩, 即,如果要在 new 时进行一些初始化操作,那么请将初始化操作单独写在
73- * init()方法中,然后在构造函数中调用该 init()方法
79+ * 可以看出来,其中都调用了init()方法,这也是一个约定俗成的规矩, 即,如果要在 new 时进行一些初始化操作,
80+ * 那么请将初始化操作单独写在 init()方法中,然后在构造函数中调用该 init()方法
7481 */
7582 public Thread () {
7683 daemon = false ;
@@ -261,6 +268,51 @@ public class Thread implements Runnable {
261268 }
262269
263270 private native void interrupt0 ();
271+
272+ /**
273+ * 线程main 调用了线程A的join方法,则 线程main 会被阻塞,直到线程A执行完毕
274+ */
275+ public final void join () throws InterruptedException {
276+ join(0 );
277+ }
278+
279+ /**
280+ * 实际上是利用 wait/notify机制 来实现的
281+ */
282+ public final synchronized void join (long millis ) throws InterruptedException {
283+ long base = System . currentTimeMillis();
284+ long now = 0 ;
285+
286+ if (millis < 0 ) {
287+ throw new IllegalArgumentException (" timeout value is negative" );
288+ }
289+ // millis 为 0,所以走这个分支
290+ if (millis == 0 ) {
291+ // 当前线程是否还在运行,还在运行 则main线程 进入等待状态,直到 A线程运行完毕,将其唤醒
292+ while (isAlive()) {
293+ wait(0 );
294+ }
295+ } else {
296+ while (isAlive()) {
297+ long delay = millis - now;
298+ if (delay <= 0 ) {
299+ break ;
300+ }
301+ wait(delay);
302+ now = System . currentTimeMillis() - base;
303+ }
304+ }
305+ }
306+
307+ /**
308+ * 线程睡眠指定的时间,释放CPU资源,但不释放锁
309+ */
310+ public static native void sleep (long millis ) throws InterruptedException ;
311+
312+ /**
313+ * 线程是否还在运行
314+ */
315+ public final native boolean isAlive ();
264316}
265317```
266318之前一直对线程状态 及 状态切换的概念模糊不清,现在通过源码中对线程状态的定义,我们可以画张图来重新回顾一下,以使我们对其有更加深刻的理解。
0 commit comments