线程有哪些状态?
线程通常有五个状态:创建,就绪,运行,阻塞,死亡
-
新建状态:新创建了一个线程对象。
-
就绪状态:线程对象创建完毕之后,其他线程调用了该对象的start方法,虚拟机将该对象放入可运行线程池,线程对象进入就绪态,等待获取CPU时间片。
-
运行:线程对象成功获取到锁,并开始运行。
-
阻塞:线程因为某些原因放弃CPU使用权,暂时停止运行。直到线程进入就绪态,才有可能转到运行态。
阻塞分为几种情况:
等待阻塞:线程调用.wait()方法,线程会释放锁,线程会被放入等待池,然后进入阻塞状态,该线程无法自行唤醒,必须等其他线程调用notify,notifyAll()方法时才被唤醒。wait()方法时Object类的方法。
同步阻塞:当一个线程准备获取锁,发现锁已经被其他线程获取了,线程就会被放入锁池中,当前线程也就一直阻塞在这,直到成功获取锁。
其他阻塞:当线程调用Thread.sleep(),join()方法,获取发出IO请求的时候,现场就会进入阻塞状态,直到睡眠超时,join执行完毕或中断,或者IO处理完毕的时候,线程转入就绪态。sleep()是Thread类的静态方法。 -
死亡:线程执行完毕或者异常推出了run方法,线程结束生命周期。
说说sleep,wait,yield,join区别
- sleep是Thread类的静态方法,而wait是Object的方法。
- 调用sleep不会释放线程当前占有的锁,而调用wait会释放锁,并且线程进入等待池。
- 调用sleep进入睡眠,睡眠时间超时线程自动唤醒进入就绪态,而调用wait方法,线程进入阻塞,需要其他线程调用notify获取notifyAll方法唤醒才能进入就绪态。
- sleep不依赖于synchronized,而wait依赖于synchronized;因为sleep一般用于当前线程睡眠或者轮询暂停,而wait用于多线程之间通信。
- 调用yield方法,线程放弃CPU,立刻进入就绪态,可以参与抢夺锁,可能刚释放锁,该线程又重新抢到锁。
- 调用join方法,调用join方法的对象对应的线程会先执行,一直到该线程执行完毕或者中断,当前线程才会继续运行。