线程生命周期状态转换

线程生命周期的几种状态

  • 新建状态(New):新建一个线程对象。
  • 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“可运行线程池”中,变得可运行,只等待获取CPU的使用权。
  • 运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
  • 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:(1)、等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒,(2)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。(3)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
  • 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

状态转换图

生命周期状态转换

新建状态---->就绪状态

调用start()

就绪状态---->运行状态

​ 当该对象被操作系统选中,获得CPU时间片,执行代码  ​

运行状态

到运行状态后,可转变的状态比较多,可转变的状态可以分为以下几类:

  • 运行状态 ---> 阻塞状态 ---> 就绪状态

调用了自身的sleep()方法或其他线程的join()方法,进程让出CPU,然后就会进入阻塞状态,。当sleep()结束或join()结束后,该线程进入可运行状态,继续等待OS分配CPU时间片(sleep()不会释放锁资源,但是会释放 CPU 资源)。

  • 运行状态 --->就绪状态

线程调用了yield()方法,意思是放弃当前获得的CPU时间片,回到就绪状态。

  • 运行状态 ---> 锁池状态 ---> 就绪状态

当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被synchronized(同步),获取不到锁标记,将会立即进入锁池状态,等待获取锁标记,一旦线程获得锁标记后,就转入就绪状态,等待OS分配CPU时间片;

  • 运行状态 --->等待队列(等待状态)--->锁池状态 ---> 就绪状态

当线程调用wait()方法后会进入等待队列,进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒(由于notify()只是唤醒一个线程,但我们由不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,因此在实际使用时,一般都用notifyAll()方法,唤醒有所线程),线程被唤醒后会进入锁池,等待获取锁标记。当获取锁标记就进入就绪状态。(wait()会释放锁资源以及 CPU 资源) 

  • 运行状态 ---> 挂起状态 ---> 就绪状态

suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的resume()被调用,才能使得线程重新进入可执行状态。

  • 运行状态 ---> 死亡状态

run()方法或main()方法结束后,线程就进入终止状态;

总结

1、wait() 和 notify() 方法与suspend()和 resume() 方法区别:

suspend()及其它所有方法在线程阻塞时都不会释放占用的锁(如果占用了的话),而wait() 和 notify() 这一对方法则相反。

2、sleep()和wait()及yield()锁资源和cpu资源释放情况

sleep()和yield()不会释放锁资源,但是会释放 CPU 资源;

wait()会释放锁资源以及 CPU 资源

3、join方法

在线程2 中调用线程1的join方法,当线程调用了这个方法时,线程1会强占CPU资源,直到线程执行结果为止(谁调用join方法,谁就强占cpu资源,直至执行结束

4、notify()/notifyAll()

notify() 方法导致解除阻塞的线程是从因调用该对象的 wait()方法而阻塞的线程中随机选取的notifyAll()全部唤醒

5、sleep()及yield()区别

sleep()是先进入阻塞状态,结束后在进入就绪状态。yield()则是直接进入就绪状态。

yield()会让优先级同级或优先级更高的 有更高的执行机会,sleep()方法不考虑自身的优先级,所以会给比它优先级低的线程机会。

sleep()会有一interryptedException异常,要么捕捉要么显示声明抛出

sleep()方法比yield()方法有更好的移植性,通常不建议使用yield()方法来控制并发线程的执行。

  • 14
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值