状态流转图

能够被中断的阻塞称为轻量级阻塞,对应的线程状态是WAITING或者TIMED_WAITING;而像 synchronized 这种不能被中断的阻塞称为重量级阻塞,对应的状态是 BLOCKED。如图所示:调用不同 的方法后,一个线程的状态迁移过程。image.png

  1. public enum State {
  2. /**
  3. * Thread state for a thread which has not yet started.
  4. */
  5. NEW,
  6. /**
  7. * Thread state for a runnable thread. A thread in the runnable
  8. * state is executing in the Java virtual machine but it may
  9. * be waiting for other resources from the operating system
  10. * such as processor.
  11. */
  12. RUNNABLE,
  13. /**
  14. * Thread state for a thread blocked waiting for a monitor lock.
  15. * A thread in the blocked state is waiting for a monitor lock
  16. * to enter a synchronized block/method or
  17. * reenter a synchronized block/method after calling
  18. * {@link Object#wait() Object.wait}.
  19. */
  20. BLOCKED,
  21. /**
  22. * Thread state for a waiting thread.
  23. * A thread is in the waiting state due to calling one of the
  24. * following methods:
  25. * <ul>
  26. * <li>{@link Object#wait() Object.wait} with no timeout</li>
  27. * <li>{@link #join() Thread.join} with no timeout</li>
  28. * <li>{@link LockSupport#park() LockSupport.park}</li>
  29. * </ul>
  30. *
  31. * <p>A thread in the waiting state is waiting for another thread to
  32. * perform a particular action.
  33. *
  34. * For example, a thread that has called <tt>Object.wait()</tt>
  35. * on an object is waiting for another thread to call
  36. * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
  37. * that object. A thread that has called <tt>Thread.join()</tt>
  38. * is waiting for a specified thread to terminate.
  39. */
  40. WAITING,
  41. /**
  42. * Thread state for a waiting thread with a specified waiting time.
  43. * A thread is in the timed waiting state due to calling one of
  44. * the following methods with a specified positive waiting time:
  45. * <ul>
  46. * <li>{@link #sleep Thread.sleep}</li>
  47. * <li>{@link Object#wait(long) Object.wait} with timeout</li>
  48. * <li>{@link #join(long) Thread.join} with timeout</li>
  49. * <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
  50. * <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
  51. * </ul>
  52. */
  53. TIMED_WAITING,
  54. /**
  55. * Thread state for a terminated thread.
  56. * The thread has completed execution.
  57. */
  58. TERMINATED;
  59. }

1、new(新创建)

new 表示线程被创建但尚未启动的状态,当我们用new Thread()新创建一个线程时 如果线程没有开始运行 start() 方法,所以也没有开始开始执行run()方法里面的代码,那么此时他的状态就是new,而一旦线程调用了start(),他的状态就从new 变成了Runnable

2、Runnable(可运行)

java 中的Runnable 状态对应操作系统的running和ready
就是 有可能正在被执行,也可能没有正在执行,正在等待被分配的cpu资源

3、Blocked(被阻塞)

从Running状态进入blocked状态只有一种可能,就是进入synchronized保护的代码时没有抢到monitor 锁
无论是进入synchronized代码块还是 synchronized方法,都是一样的

4、Waiting(等待)

线程进入waitting状态有三种可能性

1、没有设置Timeout参数的Object.wait()方法

2、没有设置Timeout参数的Thread.join()方法

3、LockSupport.park()方法

5、Time_waiting(计时等待)

以下情况会让线程进入Time waiting状态

1、设置了时间参数的Thread.sleep(Long millis)方法

2、设置了时间参数的Object.wait(long timeout)方法

3、设置了时间参数的LockSupport.parkNanos(long nanos) 方法和 LockSupport.partUntil(long deadline)方法

6、Terminated(被终止)

进入Terminated有2中可能
1、run() 方法执行结束,线程正常退出
2、出现一个没有捕获的异常,终止了run()方法,最终导致意外终止

阻塞状态

blocked

从 blocked状态进入到runnable状态要求线程获取monitor锁

waiting

从waiting状态流转到其他状态则比较特殊
首先,该状态是不现实的,因为无论经过多久,都不会恢复
只有LockSupport.unpark()或join的线程运行结束/被中断
如果其他线程调用notify()或者notifyAll()来唤醒它,它会直接进入到Bolcked状态

因为 因为唤醒waiting线程的线程 如果调用notify()或者notifyAll(),要求必须首先持有该monitor锁,所以处于waiting状态的线程唤醒时拿不到该锁,就会进入到Bolcked状态

time_witing

Time waiting中执行notify或者notifyAll也是一样道理
如果 它的超时时间到了且能直接获取到锁/join的线程结束/被中断/调用了LockSupport.unpark(),会直接恢复到Runnable状态,而不需要经历Block 状态

线程转换的注意点

1、线程的状态是需要按照箭头方向来走的,比如线程从new 状态 是不可以直接进入到blocked状态的,他需要先经历runnable状态

2、线程生命周期不可逆:一旦进入runnable状态就不能回到new状态;一旦被终止就不可能再有任何状态变化。所以一个线程只能有一次new 和 terminated 状态 ,只有处于中间状态才可以互相转换