Java并发编程之线程状态

44 阅读2分钟

线程状态

Java中线程状态有六种,定义在Thread类中的State枚举类中

  • NEW:初始状态,线程创建之后还没有开始运行。
  • RUNNABLE:可运行状态,线程正在运行或者已经就绪等待CPU资源。
  • BLOCKED:阻塞状态,因为竞争锁而发生阻塞。
  • WAITING:等待状态,线程等待其他线程执行特定的动作。
  • TIMED_WAITING:计时等待状态,
  • TERMINATED:终止状态,线程已经执行结束。

线程状态转换

线程状态转换图.png 根据线程状态转换图,来详细介绍不同状态的转换方式

① NEW -> RUNNABLE
  • 调用线程的start()方法后,状态由NEW转换成RUNNABLE
② RUNNABLE -> WAITING

以下几种情况需要注意进入WAITING状态的是哪个线程

  • 线程t通过synchronized(obj)获取到对象锁后调用obj.wait()方法时,t线程RUNNABLE转换为WAITING
  • 调用t.join()LockSupport.park()方法,当前线程状态由RUNNABLE转换成WAITING
③ WAITING -> RUNNABLE

基于②的情况,调用obj.notify()obj.notifyAll()t.interrupt()方法时

  • 竞争锁成功,状态由WAITING转换为RUNNABLE
  • 竞争锁失败,状态由WAITING转换为BLOCKED,对应图中⑧的状态

或者调用LockSupport.unpark(t)方法时,t线程状态会由WAITING转换为RUNNABLE

④ RUNNABLE -> TIMED_WAITING

这里同样需要注意发生状态转换的是哪个线程

  • 线程t通过synchronized(obj)获取到对象锁后调用obj.wait(timeout)方法时,t线程从RUNNABLE转换为TIMED_WAITING
  • 调用Thread.sleep(timeout)t.join(timeout)LockSupport.parkNanos(timeout)LockSupport.parkUntil(timeout)时,当前线程状态由RUNNABLE转换为TIMED_WAITING
⑤ TIMED_WAITING -> RUNNABLE

基于④的情况下,当调用obj.notify()obj.notifyAll()t.interrupt()方法时,

  • 竞争锁成功,状态由TIMED_WAITING转换为RUNNABLE
  • 竞争锁失败,状态由TIMED_WAITING转换为BLOCKED,对应图中⑨的状态

调用LockSupport.unpark()方法或者线程等待时间到了,状态由TIMED_WAITING转换为RUNNABLE

⑥ RUNNABLE -> BLOCKED

当线程尝试获取synchronized对象锁时,如果竞争失败,线程状态会由RUNNABLE转换为BLOCKED

⑦ BLOCKED -> RUNNABLE

当持有synchronized对象锁的线程执行完毕,会唤醒处于BLOCKED状态的锁重新竞争,如果t线程竞争成功,状态会由BLOCKED转换为RUNNABLE

⑩ RUNNABLE -> TERMINATED

线程任务执行完毕,状态由 RUNNABLE转换为TERMINATED