0%

java | 线程状态转换

深入理解线程状态转换。

  • 单向是只能从一个状态转向另一个状态
  • 双向可以相互转向

图中的各个状态

RUNABLEJAVA 层面的状态。里面的那些运行可运行状态、运行状态、阻塞状态,JAVA 是看不出来的。

假设有线程 Thread t

NEW -> RUNNABLE

  • 当调用 t.start() 方法时,由 NEW -> RUNNABLE

RUNABLE <-> WAITING 情况2

t 线程用 synchronized(obj) 获取了对象锁后

  • 调用 obj.wait() 方法时,t 线程从 RUNNABLE -> WAITING
  • 调用 obj.notify() , obj.notifyALL(), t.interrupt() 时
    • 竞争成功,t 线程从 WAITING -> RUNNABLE
    • 竞争失败,t 线程从 WAITING -> BLOCKED

RUNNABLE <-> WAITING 情况3

  • 当线程调用 t.join() 方法时,当前线程从 RUNNABLE -> WAITING
    • 逐一时当前线程在 t 线程对象的监视器等待
  • t 线程运行结束,或调用了当前线程的 interrupt() 时,当前线程从 WAITING -> RUNNABLE

RUNNABLE <-> WAITING 情况4

  • 当前线程调用了 LockSupport.park() 方法会让当前线程从 RUNNABLE -> WAITING
  • 调用 LockSupport.unpark(目标线程) 或调用了线程的 interrupt(),会让目标线程从 WAITING -> RUNNABLE

RUNNABLE <-> TIMED_WAITING 情况5

  • t 线程用 synchronized(obj) 获取对象锁后
    • 调用 obj.wait(long n) 方法,t 线程从 RUNNABLE -> TIMED_WAITING
    • t 线程等待时间超过 n 毫秒,或调用 obj.notify()obj.notifyAll()t.interrupt()
      • 竞争锁成功,t 线程从 TIMED_WAITING -> RUNNABLE
      • 竞争锁失败,t 线程从 TIMED_WAITING -> BLOCKED

RUNNABLE <-> TIMED_WAITING 情况6

  • 当前线程调用 t.join(long n) 方法时,当前线程从 RUNNABLE -> TIMED_WAITING
    • 注意时当前线程在 t 线程对象的监视器等待
  • 当前线程等待时间超过了 n 毫秒,或 t 线程运行结束,或调用了当前线程的 interrupt() 时,当前线程从 TIMED_WAITING -> RUNNABLE

RUNNABLE <-> TIMED_WAITING 情况7

  • 当前线程调用 Thread.sleep(long n),当前线程从 RUNNABLE -> TIMED_WAITING
  • 当前线程等待时间超过 n 毫秒,当前线程从 TIMED_WAITING -> RUNNABLE

RUNNABLE <-> TIMED_WAITING 情况8

  • 当前线程调用 LockSupport.parkNanos(long nanos)LockSupport.parkUntil(long millils) ,当前线程从 RUNNABLE -> TIMED_WAITING
  • 调用 LockSupport.unpark(目标线程) 或调用了线程的 interrupt(),或是等待超时,会让目标线程从 TIMED_WAITING -> RUNNABLE

RUNNABLE <-> BLOCKED 情况9

  • t 线程用 sybchronized(obj) 获取了对象锁时如果竞争失败,从 RUNNABLE -> BLOCKED
  • obj 锁线程的同步代码块执行完毕,会唤醒该对象所有的 BLOCKED 线程重新竞争,如果其中 t 线程竞争成功,从 BLOCKED -> RUNNABLE,其他失败线程依然 BLOCKED

RUNNABLE <-> TERMINATED 情况10

当前线程执行完毕,进入 TERMINATED

请我喝杯咖啡吧~