通常来讲, 线程有5种状态,分别是开始,可运行,运行汇总,阻塞,死亡,其中,阻塞分为三种情况,同步阻塞,等待阻塞和其他阻塞,线程各种状态之间的关系大体如下图所示
下面对各个状态进行详细解读
1new :创建出线程,即new出线程,即完成了第一阶段;
2runnable,创建的线程调用start方法则进入runnable阶段,运行中的线程被cpu切出,也进入了runnable阶段,阻塞状态的线程,其阻塞条件解除后会进入runnable状态;
3running状态,任何runnable状态的线程都可以进入running状态,java的线程是抢占是调度,所以具体执行哪一个线程是不确定的,其执行收到线程权重的影响,runnable状态线程获得cpu的timeslice即进入running状态;运行状态的线程调用yield()方法会进入runnable状态;
4dead,死亡状态,线程执行结束 也可以说run方法执行结束,即进入死亡状态,对于守护线程,当没有非守护线程运行时,其也进入死亡状态(不管其run方法有没有执行完成)
5blocked,阻塞状态,这个状态有多种情况
1等待阻塞,拿到对象锁的线程,调用wait()方法会被放进等待队列waitting queue中,等待阻塞的线程被notify后进入lock pool,等待争抢对象锁,从而可以进入runnable状态;wait()方法是会释放对象锁的;
2同步阻塞,当一个线程运行到同步方法,并且没有获取同步锁时会进入lock pool中,一旦同步锁被释放,则进入锁的争抢,争抢到后,即可进入runnable状态,值得注意的是,持有对象锁不意味着可以一直执行下去,未持有该同步锁的线程可以执行该对象的非同步方法,某一时刻具体执行哪个线程是由cpu调度的;每一个对象都有一个lock pool,等待争抢这个对象锁的线程都会在该对象的lock pool中
3其他阻塞,线程调用sleep()进入阻塞状态,IO阻塞,或者调用其他线程的join()方法使当前线程进入阻塞,这些阻塞都称为其他阻塞;当这些条件解除(sleep时间到了,IO阻塞解除,join的线程执行完毕)后,阻塞的线程会进入runnable状态;注意,当A线程调用B线程的join()方法时,A线程不会释放对象的锁;