多线程分为5种状态:
新建(New):新建线程在jvm虚拟机栈里,线程栈是私有的。而jvm中的本地方法栈是用于本地native方法的私有栈。
就绪(Runnable):也叫“可执行状态”调用start进入可执行状态后并不是马上运行,而是处于可运行线程池中随时待命等待CPU的调度。
运行(Running):当获取到CPU执行权边开始从就绪状态变成运行状态,开始执行run()里面的方法。
阻塞(Blocked):当失去 cpu 使用权的时候,便进入到阻塞状态,等待再次抢占资源进入就绪(runnable)状态才有机会获得运行。阻塞分三种情况:
1).等待阻塞:执行wait()方法,JVM将线程放入等待队列(waitting queue)中。
2).同步阻塞:运行的线程在获取对象同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
3).其他阻塞:执行sleep()或join()方法,或者I/O请求时,JVM会把线程置为阻塞状态。死亡(Dead):在线程执行完run()、main()方法后线程结束,或者因为某种异常或者错误而终止运行。
以下是从网上找到的一张状态转化图:
以上图比较详细,只说几个需要注意的点:
1.sleep()与wait()的区别:都使线程从running变成blocked状态,但是sleep是Thread类的方法,wait是Object的方法,所以sleep不能改变对象锁也就不能释放锁资源,仍然占有锁资源,而wait会释放当前对象的锁资源。
2.阻塞恢复的线程不一定会马上去执行,因为CPU可能还在执行其他的任务,只是拥有CPU执行权继续竞争。
3.join():等待别的线程执行完了自己再执行。
4.yield():是将running中的线程“退让”成runnable的状态,也就是让执行中的线程编程可执行的状态重新进行竞争(不一定能竞争上)。