Java基础 -> 线程的生命周期?线程有几种状态?

线程的生命周期?线程有几种状态?

线程通常有五种状态,创建,就绪,运⾏、阻塞和死亡状态:

  1. 创建状态(New):新创建了⼀个线程对象。

    • 仅仅是线程对象,操作系统线程还没有创建
    • 关键操作: new Thread();
  2. 就绪状态(Runnable):线程对象创建后,其他线程调⽤了该对象的start⽅法。该状态的线程位于 可运行线程池中,变得可运⾏,等待获取CPU的使⽤权。

    • 操作系统创建线程,线程进入一个类似等待CPU线程队列(名字我自己起的,包括下面的队列),等待获取CPU的使⽤权
    • 关键操作: start();
  3. 运⾏状态(Running):就绪状态的线程获取了CPU,执⾏程序代码。

    • 关键操作: run();
  4. 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停⽌运⾏。直到线程进⼊就绪状态,才有机会转到运⾏状态。

    • 线程进入阻塞队列(不让cpu执行的队列),放弃CPU使⽤权
    • 等待从阻塞队列弹出,再次进入CPU队列,就是就绪状态
    • 关键操作: wait() notify() sleep() join() yield()
  5. 死亡状态(Dead):线程执⾏完了或者因异常退出了run⽅法,该线程结束⽣命周期。

再这些状态中,阻塞状态是知识点最多的,也是最主要的点

阻塞的情况⼜分为三种:

  1. 等待阻塞:运⾏的线程执⾏wait⽅法,该线程会释放占⽤的所有资源,JVM会把该线程放⼊“Wait Set(等待集)”中。进⼊这个状态后,是不能⾃动唤醒的,必须依靠其他线程调⽤notify或notifyAll⽅法才能被唤醒

    • 内部锁

      • 每个对象都有内部锁,内部锁会维护两个集合结构
      • Entry Set(网上有叫锁池): 多个线程抢锁,没抢到的线程加入锁池(Entry Set)
      • Wait Set(网上有叫等待池): 调用wait⽅法阻塞的线程,会加入这个等待池Wait Set
      • 一个线程只能加入锁池或者等待池,线程不管加入哪个池,都代表此时已经不在持有锁了
        • 没抢到锁的,不持有锁,调用wait方法的也不持有锁
    • 这种情况的特点是 -> 主动将线程从cpu队列弹出,加入到阻塞队列中

    • 相对的需要 -> 主动让线程从阻塞队列弹出,加入cpu队列,才能正常运行线程

    • 注意: 会释放锁 -> 只有这里会释放锁,下面情况的都不会释放锁

  2. 同步阻塞:运⾏的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放⼊“Entry Set(锁池)”中。

    • 这种情况的特点是 -> 锁被占用被动的阻塞了线程,使得线程不能正常工作
  3. 其他阻塞:运⾏的线程执⾏sleep或join⽅法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep状态超时、join等待线程终⽌或者超时、或者I/O处理完毕时,线程重新转⼊就绪状态。sleep是Thread类的⽅法

    • 这种情况的特点是 -> 主动将线程放弃CPU使用权,加入到阻塞队列中
    • 相对的 -> 超时或者完成规定的要求后从阻塞队列弹出,加入cpu队列,正常运行线程
    • 注意: 锁不会释放 -> 锁的释放是在对象上的,主动释放锁的方式只有再对象上调用wait方法,join方法也可以释放锁,join方法内部也是调用wait方法

点赞.靓仔

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值