面试官:
画个图给我说一下线程有哪几种状态,以及各个状态间的转换。
阿满:
这TM鬼才会啊,哪有直接让你画图的,一下子全画出来怎么可能,T T。
下面我们就来一步步的把这个图画出来,让面试官B嘴
这里初次记忆起来可能比较困难,不过不用担心,因为后续随着线程间各种方法的学习和使用,自然而然就会慢慢理解了。
为了让大家更好的记忆,我们一起来理一遍。
主要流程:
- 实例化,也就是new一个线程以后,线程就进入了初始化的阶段。2.调用线程的start方法,线程进入运行状态。3. 线程执行完毕,进入中止状态。
各种分支流程。1. 共性:都是由运行状态变换开去的。 - 运行状态包含了2种,运行中 以及 就绪,这2种线程的切换主要是通过cpu的调度以及线程主动调用yield()方法,背后实现就是让出cpu的时间片进去就绪状态,然后获取到cpu的时间片,进入到运行中的状态。
- 运行状态<—> 等待状态。这里分为2类方法,一类是Object类的2个方法,wait() 和join()。一类是JUC包下的LockSupport的park()方法。相对的,从等待到运行,就是Object类的notify(),notifyAll()以及LockSupport的unpark(Thread)方法。
- 运行状态<—>超时等待状态。这里分为3类,一类是Thread类的方法,包括sleep(long),join(long),一类是Object类的方法,wait(long),另外一类是LockSupport类的方法,parkNacos()以及parkUntil()方法。从超时等待到运行状态,分为2类方法,一类是Object类的notify(),一类是notifyAll(),另外一类是LockSupport类的unpark(Thread)方法。
- 运行状态<—> 阻塞状态。这里主要是线程在等待获取锁的时候的状态转换,如果所需要获取的锁当前被其他线程占用(准确说是锁了某个线程中的某个对象或代码块),则会进入阻塞状态,当阻塞状态的线程获取到锁后,则进入运行状态。