线程的状态转换和调度

devtools/2025/2/3 11:06:35/

  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.ppmy.cn/devtools/155701.html

相关文章

python算法和数据结构刷题[6]:二叉树、堆、BFS\DFS

遍历二叉树 前序遍历NLR:先访问根结点,再前序遍历左子树,最后前序遍历右子树。中序遍历LNR:先中序遍历左子树,再访问根结点,最后中序遍历右子树。后序遍历 LRN:先后序遍历左子树,再…

【Linux探索学习】第二十七弹——信号(一):Linux 信号基础详解

Linux学习笔记: https://blog.csdn.net/2301_80220607/category_12805278.html?spm1001.2014.3001.5482 前言: 前面我们已经将进程通信部分讲完了,现在我们来讲一个进程部分也非常重要的知识点——信号,信号也是进程间通信的一…

深度学习查漏补缺:2. 三个指标和注意力机制

一、bachsize, num_epochs, dataset 在训练卷积神经网络(CNN)或任何其他深度学习模型时,有几个关键参数和概念需要了解:batch size、num epochs 和 dataset。下面是对它们的详细解释: Batch Size(批量大小&…

核心集:DeepCore: A Comprehensive Library for CoresetSelection in Deep Learning

目录 一、TL;DR 二、为什么研究核心集? 三、问题定义和如何做 3.1 问题定义 3.2 业界方法 3.2.1 基于几何的方法 3.2.2 基于不确定性的方法 3.2.3 基于误差/损失的方法 3.2.5 GraNd 和 EL2N 分数 3.2.6 重要性采样 3.2.7 基于决策边界的办法 …

小程序-基础加强-自定义组件

前言 这次讲自定义组件 1. 准备今天要用到的项目 2. 初步创建并使用自定义组件 这样就成功在home中引入了test组件 在json中引用了这个组件才能用这个组件 现在我们来实现全局引用组件 在app.json这样使用就可以了 3. 自定义组件的样式 发现页面里面的文本和组件里面的文…

【Linux网络编程】数据链路层

前言: 数据链路层非常简单,对于程序员来说,这里只需要大致了解即可,本篇文章不做重点说明。 数据链路层介绍 数据链路层是OSI位于物理层之上和网络层之下,这一层的报文叫做帧。它的主要任务是确保数据从一个节点可靠地…

基于 YOLOv8+PyQt5 界面自适应的无人机红外目标检测系统项目介绍框架

基于 YOLOv8PyQt5 界面自适应的无人机红外目标检测系统项目介绍框架 【毕业与课程大作业参考】基于yolov8pyqt5界面自适应的无人机红外目标检测系统demo.zip资源-CSDN文库 (毕业设计 / 课程大作业参考方案) 一、项目背景与意义 无人机在军事侦察、灾害…

【C语言设计模式学习笔记1】面向接口编程/简单工厂模式/多态

面向接口编程可以提供更高级的抽象,实现的时候,外部不需要知道内部的具体实现,最简单的是使用简单工厂模式来进行实现,比如一个Sensor具有多种表示形式,这时候可以在给Sensor结构体添加一个enum类型的type,…