java线程状态
线程状态
1、新建(New)
新创建了一个线程对象,还未调用start()方法。
2、就绪(Ready)
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中 获取cpu 的使用权 。
3、运行中(Running)
可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
4、限期等待(Timed Waiting)
也可以称作 TIMED_WAITING(有等待时间的等待状态)。
线程主动调用以下方法:
Thread.sleep方法;
Object的wait方法,带有时间;
Thread.join方法,带有时间;
LockSupport的parkNanos方法,带有时间。
5、无限期等待(Waiting)
运行中(Running)的线程执行了以下方法:
Object的wait方法,并且没有使用timeout参数;
Thread的join方法,没有使用timeout参数;
LockSupport的park方法;
Conditon的await方法。
6、阻塞(Blocked)
阻塞状态是指线程因为某种原因放弃了cpu 使用权,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分两种:
同步阻塞:运行(running)的线程进入了一个synchronized方法,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
其他阻塞:运行(running)的线程发出了I/O请求时,JVM会把该线程置为阻塞状态。当I/O处理完毕时,线程重新转入可运行(runnable)状态。
7、结束(Terminated)
线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。
状态图
等待队列
调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) 代码段内。
与等待队列相关的步骤和图
同步队列状态
- 当前线程想调用对象A的同步方法时,发现对象A的锁被别的线程占有,此时当前线程进入同步队列。简言之,同步队列里面放的都是想争夺对象锁的线程。
- 当一个线程1被另外一个线程2唤醒时,1线程进入同步队列,去争夺对象锁。
- 同步队列是在同步的环境下才有的概念,一个对象对应一个同步队列。
- 线程等待时间到了或被notify/notifyAll唤醒后,会进入同步队列竞争锁,如果获得锁,进入RUNNABLE状态,否则进入BLOCKED状态等待获取锁。
几个方法比较
- Thread.sleep(long
millis),一定是当前线程调用此方法,当前线程进入TIMED_WAITING状态,但不释放对象锁,millis后线程自动苏醒进入就绪状态。作用:给其它线程执行机会的最佳方式。 - Thread.yield(),一定是当前线程调用此方法,当前线程放弃获取的CPU时间片,但不释放锁资源,由运行状态变为就绪状态,让OS再次选择线程。作用:让相同优先级的线程轮流执行,但并不保证一定会轮流执行。实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。Thread.yield()不会导致阻塞。该方法与sleep()类似,只是不能由用户指定暂停多长时间。
- t.join()/t.join(long
millis),当前线程里调用其它线程 t的join方法,当前线程进入WAITING/TIMED_WAITING 状态,当前线程不会释放已经持有的对象锁。线程t执行完毕或者millis时间到,当前线程进入就绪状态。 - obj.wait(),当前线程调用对象的wait()方法,当前线程释放对象锁,进入等待队列。依靠notify()/notifyAll()唤醒或者wait(long
timeout) timeout时间到自动唤醒。 - obj.notify()唤醒在此对象监视器上等待的单个线程,选择是任意性的。notifyAll()唤醒在此对象监视器上等待的所有线程。
转载:https://blog.****.net/pange1991/article/details/53860651
https://www.jianshu.com/p/dbbcceb6bc2a