线程的状态(五种?六种?)

64 阅读3分钟

从操作系统层面来描述:

  • 1、初始状态 仅在语言层面创建了线程对象,还未与操作系统线程关联
  • 2、可运行状态 就绪状态,指该线程已经被创建(与操作系统线程关联),可以由CPU调度执行
  • 3、运行状态 指获取了CPU时间片运行中的状态,当CPU时间片用完,会从运行状态切换至可运行状态,会导致线程上下文切换
  • 4、阻塞状态 如果调用了阻塞API,如BIO读写文件,这是线程实际不会用到CPU,会导致线程上下文切换,进入阻塞状态 等BIO操作执行完毕,会由操作系统唤醒阻塞的线程,切换至可运行状态 与可运行状态的区别是,对阻塞状态的线程来说只要它们一直不唤醒,调度器就一直不会考虑调度它们
  • 5、终止状态 表示线程已经执行完毕,生命周期已经结束,不会再转换为其他状态

image.png

从Java API层面描述的,Thread类中的State枚举定义的六种状态:

  • NEW 线程刚被创建,但是还没有调用start()方法 同五种状态中的 初始状态是一致的
  • RUNNABLE 当调用了start()方法之后,注意Java API层面的RUNNABLE状态涵盖了操作系统层面 可运行状态、运行状态和阻塞状态(操作系统层面)(由于BIO导致的线程阻塞,在Java里无法区分,仍然认为是可运行状态)
  • BLOCKED 等待获取锁
  • WAITING join
  • TIMED_WAITING sleep(1000)
  • TERMINATED 线程执行完毕进入终止状态 与操作系统中的终止状态一致

image.png

image.png

状态转换图中的编号:

  1. 调用线程对象的start()方法,将Java的线程关联到操作系统的线程,变为RUNNABLE
  2. 线程使用synchronizd(obj)获取到对象锁之后,调用obj.wait() 线程从RUNNANLE 变为 WAITING,当调用obj.notify(),obj.notifyAll(),t.interrupt()时,如果竞争锁成功,t线程从 WAITING变为 RUNNABLE。如果获取锁失败,t线程从WAITING变为BLOCKED
  3. 当前线程调用t.join()方法时,当前线程从RUNNABLE状态变为WAITING 注意是当前线程在t线程对象的监视器上等待。t线程运行结束,或调用了当前线程的interrupt()时,当前线程从WAITING变为RUNNABLE状态
  4. 当线程调用LockSupport.park()方法会让当前线程从RUNNABLE变为WAITING,调用LockSupport.unpark(目标线程)或调用线程的interrupt(),会让目标线程从WAITING变为RUNNABLE
  5. 线程使用synchronized(obj)获取对象锁后,调用obj.wait(long n)方法,线程从RUNNABLE变为TIMED_WAITING状态,线程等待时间超过了n毫秒,或者调用了obj.notify(),obj.notifyAll(),t.interrupt()时,如果竞争锁成功 线程从TIMED_WAITING变为RUNNABLE,如果竞争锁失败,从TIMED_WAITING变为BLOCKED状态
  6. 当线程调用t.join(long n)方法时,当前线程从RUNNABLE变为TIMED_WAITING,注意是当前线程在t线程对象的监视器上等待。当前线程等待时间超过了n毫秒,或t线程运行结束,或者调用了当前线程的interrupt()时,当前线程从TIMED_WAITING变为RUNNABLE
  7. 当前线程调用Thread.sleep(long n) 当前线程从RUNNABLE状态变为TIMED_WAITING状态,当前线程等待时间超过了n毫秒,当前线程从TIMED_WAITING变为RUNNABLE
  8. LockSupport.parkNanos(long nanos)或LockSupport.parkUntil(long deadline)时,当前线程从RUNNABLE变为TIMED_WAITING状态,调用LockSupport.unpark(目标线程)或调用线程的interrupt,或者等待超时,会让目标线程从TIMED_WAITING变为RUNNABLE
  9. 当线程用synchronized(obj)获取锁时如果竞争失败,从RUNNABLE变成BLOCKED,当持有锁的线程代码执行完毕会唤醒该对象上所有BLOCKED的线程重新竞争锁,如果线程竞争成功,从BLOCKED变为RUNNABLE,其他失败的线程仍然BLOCKED
  10. 当前线程所有代码运行完毕,进入TERMINATED