当前位置: 首页 > article >正文

线程的状态转换和调度

  1. 新建状态New:新创建了一个线程对象

  2. 可运行状态Runnable:线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。

  3. 运行状态Running:可运行状态的线程获取了CPU资源时,执行程序run()方法代码。

  4. 阻塞状态Blocked:线程由于某种原因放弃CPU使用权,暂时停止运行。阻塞的情况分两种种:

    1. 同步阻塞:对象的同步锁被其他的线程占用时,则JVM会把该线程放入锁池中等待锁释放。

    2. 其他阻塞:当运行的线程执行sleep()join()方法,或发起I/O请求时,该线程将进入阻塞状态。在此期间,线程不会释放已持有的锁,一旦 sleep() 调用完成、join() 方法的等待线程终止或超时,或者 I/O 操作完成,线程将返回到可运行状态

  5. Waiting(等待状态): 运行的线程执行wait()方法,JVM会把该线程放入等待池中。需要被显式唤醒才能继续执行。

  6. Timed Waiting(含等待时间的等待状态): 线程进入等待状态,但指定了等待时间,超时后会被唤醒

  7. 终止状态(Terminated):线程正常完成了run() 方法执行流程 或 异常而提前退出时,该线程结束生命周期。

线程的调度
  1. 调整线程优先级:Java线程有优先级,且有继承关系(如A线程中创建B线程,AB优先级一样),优先级高的线程可能更先运行

static int MAX_PRIORITY
          线程可以具有的最高优先级,取值为10。
static int MIN_PRIORITY
          线程可以具有的最低优先级,取值为1。
static int NORM_PRIORITY
          分配给线程的默认优先级,取值为5。
  1. 线程睡眠:Thread.sleep(long millis)方法,使线程转到阻塞状态。millis参数设定睡眠的时间,以毫秒为单位。当睡眠结束后,就转为可运行状态 ,sleep() 方法的实现是平台无关的,可以在不同的操作系统上正常工作

  2. 线程等待:调用Object.wait()方法,释放了当前线程持有的对象锁,并将线程放入等待池中,直到其他线程调用此对象锁(Object)的notify()notifyAll()方法唤醒 等待池中的一个或多个对象

    • 如果多个线程都在等待同一个对象锁,则 notify() 方法只会唤醒其中一个线程,而 notifyAll() 则会唤醒所有等待中的线程,重新竞争该对象的锁

  3. 线程让步:调用Thread.yield()方法,让当前运行线程回到可运行状态,把执行机会让给自己,相同或者更高优先级的线程

  4. 线程加入:调用Thread.join()方法,可以让当前线程等待另一个线程的终止。即在当前线程中调用另一个线程的 join() 方法,当前线程将会进入阻塞状态,直到另一个线程运行结束,然后恢复到可运行状态

  5. 线程唤醒:调用 Object.notify() 方法,可以唤醒一个在该对象上等待的线程。如果多个线程都在等待同一个监视器,则 notify() 方法会随机选择一个线程来唤醒。。而 notifyAll() 方法则会唤醒所有在该对象监视器上等待的线程,被唤醒的线程需要重新竞争对象锁才能继续执行。

例子说明

注意点

  • wait,notify和 notifyAll 只能在同步锁方法或者同步控制块里面使用,而sleep可以在任何地方使用

  • 当线程离开一个同步块后,会自动释放该同步块持有的锁,这是Java规范

//wait用法
public class MyThreadPrinter2 implements Runnable {   
   private String name;   
   private Object prev;   
   private Object self;   
   private MyThreadPrinter2(String name, Object prev, Object self) {this.name = name; this.prev = prev;this.self = self;}   
​
   @Override  
   public void run() {   
       int count = 10;   
       while (count > 0) {   
           synchronized (prev) {     //先持有前一个线程所持有的对象锁前提下 
               synchronized (self) {      //持有自身对象锁      
                   System.out.print(name);   
                   count--;           
                   self.notify();   //唤醒一个在当前对象上等待的线程  
                 }   
               //自动释放self锁
             try {   
               prev.wait();     //释放prev对象锁,终止该锁上的当前线程
           } catch (InterruptedException e) {   
               e.printStackTrace();   
           }   
       }   
   }     
   public static void main(String[] args) throws Exception {   
       Object a = new Object();   
       Object b = new Object();   
       Object c = new Object();   
       MyThreadPrinter2 pa = new MyThreadPrinter2("A", c, a);  
       MyThreadPrinter2 pb = new MyThreadPrinter2("B", a, b);  
       MyThreadPrinter2 pc = new MyThreadPrinter2("C", b, c);         
      //整体过程
       //A线程最先运行,持有c,a对象锁-->唤醒B-->释放a锁-->释放c锁
                                //线程B持有a,b锁,执行同步代码块后-->唤醒C-->释放b锁-->释放a锁
                                                        //线程C持有b,c锁,执行同步代码块后-->唤醒A-->释放c锁-->释放b锁
    
 
       new Thread(pa).start();
       Thread.sleep(100);       //确保按顺序A、B、C执行
       new Thread(pb).start();
       Thread.sleep(100);  
       new Thread(pc).start();   
       Thread.sleep(100);  
   }   
}  
//输出结果:
//ABCABCABCABCABCABCABCABCABCABC


http://www.kler.cn/a/528932.html

相关文章:

  • 计算机网络一点事(24)
  • 好用的翻译工具
  • AI协助探索AI新构型的自动化创新概念
  • MySQL 插入数据
  • DeepSeek 云端部署,释放无限 AI 潜力!
  • 【AI】DeepSeek 概念/影响/使用/部署
  • 深入理解Spring框架:从基础到实践
  • python学opencv|读取图像(五十三)原理探索:使用cv.matchTemplate()函数实现最佳图像匹配
  • 996引擎 -地图-添加安全区
  • 群速度与相速度辨析
  • NIST的 临床质量指标的简介
  • arkui-x 页面封装为自定义组件,巧用controller
  • Spring的AOP思想中事物管理注意点
  • 基础数据类型之整形
  • (leetcode 213 打家劫舍ii)
  • Games104——游戏引擎Gameplay玩法系统:基础AI
  • 从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(动态菜单组件实现)
  • Dijkstra算法解析
  • 读书笔记-《Redis设计与实现》(一)数据结构与对象(下)
  • 课题介绍:水下惯性/地形组合导航精度提升的理论与方法研究
  • oracle: 多表查询之联合查询[交集intersect, 并集union,差集minus]
  • 环形缓冲区原理与C语言实现ringbuffer
  • 计算满足特定条件的素数在全体素数中的密度极限值,并将该极限值乘以10^7后向下取整的解题思路
  • Python3 【装饰器】项目实战:5个新颖的学习案例
  • 说说Redis的内存淘汰策略?
  • TVM调度原语完全指南:从入门到微架构级优化