线程休眠、线程让步、线程优先级相关内容学习笔记
1、线程休眠
(1)sleep()
如果需要让当前正在执行的线程暂停一段时间,并进入阻塞状态(Timed_Waiting),则可以通过调用Thread类的静态sleep()方法来实现。
static void sleep(long millis):让当前正在执行的线程暂停millis毫秒,并进入阻塞状态,该方法受到系统计时器和线程调度器的精度与准确度的影响。
static void sleep(long millis,int nanos):让当前正在执行的线程暂停millis毫秒加nanos毫微秒,并进入阻塞状态,该方法受到系统计时器和线程调度器的精度与准确度的影响。
当前线程调用 sleep()方法进入阻塞状态后,在其睡眠时间段内,该线程不会获得执行的机会,即使系统中没有其他可执行的线程,处于sleep()中的线程也不会执行,因此sleep()方法常用来暂停程序的执行。
/**
* sleep()方法练习
*/
public class SleepDemo1 {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
while(true){
System.out.println(true);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
//t1不调用start()方法 只调用run()方法时
//此时只有main线程运行 调用sleep()休眠的是mian线程
t1.run();
System.out.println("main线程休眠");
}
}
/**
* sleep()方法练习
*/
public class SleepDemo2 {
public static void main(String[] args) throws InterruptedException {
Thread t2 = new Thread(()->{
while(true){
System.out.println(true);
try {
//t2线程休眠 无法在休眠时间段内唤醒线程
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
t2.start();
//休眠主线程 确保t2线程执行
TimeUnit.SECONDS.sleep(3);
//sleep()休眠后 t2线程的状态为TIME_WAITING
System.out.println(t2.getState());//TIMED_WAITING
}
}
/**
* sleep()方法练习
*/
public class SleepDemo3 {
public static void main(String[] args) throws InterruptedException {
Thread t3 = new Thread(()->{
while(true){
System.out.println(true);
}
});
t3.start();
//注意 sleep()是类方法 能使用创建对象的方式调用,但是不会有休眠效果,所以不能使用这种方式调用sleep()方法
t3.sleep(1000);
//休眠主线程 确保t2线程执行
TimeUnit.SECONDS.sleep(3);
//此时,t2线程不会被休眠
}
}
/**
* Interrupt()方法
*/
public class InterruptedDemo {
public static void main(String[] args) {
Thread t4 = new Thread(()->{
while (true){
System.out.println(true);
}
});
t4.start();
//调用interrupt()方法无法中断线程
//只能采用先标记线程中断
//然后通过Thread.interrupted();判断线程状态是否为中断状态
//若为true则通过抛异常的方式中断程序
t4.interrupt();
}
}
(2) LockSupport类
LockSupport是JUC提供的一个线程阻塞与唤醒的工具类,该工具类可以让线程在任意位置阻塞和唤醒,其所有的方法都是静态方法。
/**
* park()方法练习
*/
public class LockSupportDemo1 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(()->{
System.out.println("t1线程开始休眠");
//无休止休眠 t1线程为阻塞态 为Waiting
LockSupport.park();
System.out.println("t1线程结束休眠");
});
//启动线程t1
t1.start();
//休眠主线程,让线程t1能顺利执行
TimeUnit.SECONDS.sleep(3);
System.out.println(t1.getState());//Waiting
}
}
/**
* unpark()方法练习
*/
public class LockSupportDemo2 {
public static void main(String[] args) throws InterruptedException {
Thread t2 = new Thread(()->{
System.out.println("t1线程开始休眠");
//休眠指定的时间 休眠后可以在休眠时间段内重新被唤醒 比较灵活
LockSupport.parkNanos(10000000000L);
System.out.println("t1线程结束休眠");
});
//启动线程t2
t2.start();
//休眠主线程,让线程t2能顺利执行
TimeUnit.SECONDS.sleep(3);
LockSupport.unpark(t2);
System.out.println(t2.getState());//Time_Waiting(不定)
System.out.println("线程被唤醒");
System.out.println(t2.getState());//TERMINATED
}
}
当调用park()方法时,会让线程进入WAITING状态,调用parkNanos(long nanos)方法时,线程会进入TIMED_WAITING状态
/**
* unpark()方法练习
*/
public class LockSupportDemo2 {
public static void main(String[] args) throws InterruptedException {
Thread t2 = new Thread(()->{
System.out.println("t1线程开始休眠");
//休眠指定的时间 休眠后可以在休眠时间段内重新被唤醒 比较灵活
LockSupport.parkNanos(10000000000L);
System.out.println("t1线程结束休眠");
});
//启动线程t2
t2.start();
//休眠主线程,让线程t2能顺利执行
TimeUnit.SECONDS.sleep(3);
LockSupport.unpark(t2);
System.out.println(t2.getState());//Time_Waiting(不定)
System.out.println("线程被唤醒");
System.out.println(t2.getState());//TERMINATED
}
}
LockSupport.park()和Thread.sleep()的区别:
1、Thread.sleep()无法从外部唤醒。只能自己醒过来;而被LockSupport.park()方法阻塞的线程可以通过调用LockSupport.unpark()方法去唤醒。
2、被Thread.sleep()、LockSupport.park()方法所阻塞的线程有一个特点,当被阻塞线程的Thread.interrupt()方法调用时,被阻塞线程的中断标志将被设置,该线程将被唤醒。不同的是,二者对中断信号的响应方式不同:LockSuppport.park()方式不会抛出InterruptedExcepton异常,仅仅设置了线程的中断标志;而Thread.sleep()方法会抛出InterruptedException异常
3、与Thread.sleep()相比,调用LockSupport.park()更能精准、更加灵活地阻塞、唤醒指定线程。
2、线程让步
yield()方法是一个和 sleep()方法有点相似的方法,它也是 Thread 类提供的一个静态方法,它也可以让当前正在执行的线程暂停,但它不会阻塞该线程,它只是将该线程转入就绪状态。
yield()只是让当前线程暂停一下,让系统的线程调度器重新调度一次,线程调度器会从线程就绪队列里获取一个线程优先级高的线程,当然完全可能的情况是:当某个线程调用了yield()方法暂停之后,线程调度器又将其调度出来重新执行。
当某个线程调用了yield()方法暂停之后,只有优先级与当前线程相同,或者优先级比当前线程更高的处于就绪状态的线程才会获得执行的机会。下面程序使用yield()方法来让当前正在执行的线程暂停。
/**
* yield()方法练习
*/
public class YieldDemo {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
for (int i = 1; i < 30; i++) {
System.out.println(Thread.currentThread().getName()+"=============="+i);
if(i%10==0){
//调用yield方法让t1线程暂停
Thread.yield();
}
}
},"t1");
Thread t2 = new Thread(()->{
for (int i = 0; i < 30; i++) {
System.out.println(Thread.currentThread().getName()+">>>"+i);
}
},"t2");
//yield之后,有可能原来执行的线程继续获得执行的机会
//为t1线程设置优先级
t1.setPriority(10);
//启动t1线程
t1.start();
//为t2线程设置优先级
t2.setPriority(1);
//启动t2线程
t2.start();
//优先级大的线程不一定先执行,而是执行概率大
for (int i = 0; i < 30; i++) {
System.out.println(Thread.currentThread().getName()+">>>"+i);
}
}
}
3、线程优先级
每个线程执行时都具有一定的优先级,优先级高的线程获得较多的执行机会,而优先级低的线程则获得较少的执行机会。每个线程默认的优先级都与创建它的父线程的优先级相同,在默认情况下,main线程具有普通优先级,由main线程创建的子线程也具有普通优先级。
Thread类提供了setPriority(int newPriority)、getPriority()方法来设置和返回指定线程的优先级,其中setPriority()方法的参数可以是一个整数,范围是1~10之间,也可以使用Thread类的如下3个静态常量。
MAX_PRIORITY:其值是10。
MIN_PRIORITY:其值是1。
NORM_PRIORITY:其值是5。
/**
* 优先级练习
*/
public class PriorityDemo {
public static void main(String[] args) throws InterruptedException {
//定义存放线程的数组
MyThread[] myThreads = new MyThread[10];
int length = myThreads.length;
//优先级为1<-->10 循环需要从1开始
for (int i = 1; i <=length; i++) {
//创建线程
myThreads[i-1] = new MyThread();
//分别创建线程优先级
myThreads[i-1].setPriority(i);
//启动线程
myThreads[i-1].start();
}
//休眠主线程 让创建的线程得以执行
TimeUnit.SECONDS.sleep(3);
for (int i = 0; i < length; i++) {
//停止线程
myThreads[i].stop();
}
}
}
优先级的继承
/**
* 优先级练习2
*/
public class PriorityDemo2 {
public static void main(String[] args) {
Thread thread = new Thread(()->{
System.out.println("线程thread执行");
},"thread");
Thread main = Thread.currentThread();
System.out.println(main.getState());
System.out.println(main.getName()+"线程的优先级:"+main.getPriority());
//在main线程中创建thread线程,thread线程的优先级与main线程一致
thread.start();
System.out.println(thread.getName()+"线程的优先级:"+thread.getPriority());
}
}
相关文章:
线程休眠、线程让步、线程优先级相关内容学习笔记
1、线程休眠 (1)sleep() 如果需要让当前正在执行的线程暂停一段时间,并进入阻塞状态(Timed_Waiting),则可以通过调用Thread类的静态sleep()方法来实现。 static void sleep(long millis):让当前正在执行的线…...
paddle指定运行gpu
在PaddlePaddle中指定使用GPU进行运行非常简单。首先,确保你的机器上已经安装了CUDA和cuDNN,并且正确配置了GPU环境。然后,按照以下步骤进行操作: 导入PaddlePaddle库: import paddle设置使用的设备为GPU:…...

Java异常及网络编程
异常续 throws关键字 当一个方法中使用throw抛出一个非RuntimeException的异常时,就要在该方法上使用throws声明这个异常的抛出。此时调用该方法的代码就必须处理这个异常,否则编译不通过。 package exception; /*** 测试异常的抛出*/ public clas…...

通过 Elastic Stack 充分利用电信领域生成式 AI 的力量
作者:Elastic Piotr Kobziakowski, Jrgen Obermann 在瞬息万变的电信领域,Elastic Stack 与生成式 AI 的集成正在开创运营效率和创新的新时代。 这些技术不仅增强了网络运营,而且还彻底改变了各个部门的内部流程。 下面,我们将深入…...

Redis:原理速成+项目实战——Redis实战8(基于Redis的分布式锁及优化)
👨🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:Redis:原理速成项目实战——Redis实战7(优惠券秒杀细节解决超卖、一人一单问题) Ὅ…...

江山易改本性难移之ZYNQ SDK QSPI固化bug及其解决方法
之前在Vivado2018.3通过QSPI方式固化程序时出现问题,显示flash擦除成功,但最后总是不能写入到flash中。 查资料发现从VIVADO 2017.3版本开始,Xilinx官方为了使Zynq-7000和Zynq UltraScale 实现流程相同,在QSPI FLASH使用上做了变化…...
系列三十六、注解版Spring、SpringMVC配置文件
一、注解版Spring、SpringMVC配置文件 1.1、pom <dependencies><!-- SpringMVC --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.1.5.RELEASE</version><…...

爬虫你需要知道的:什么是http请求
1. 什么是http请求 我们将通过发送http请求来获取网页内容。http是HyperText Transfer Protocol的缩写,意思是超文本传输协议,它是一种客户端和服务器之间的请求响应协议。 浏览器就可以看作是一个客户端,当我们在浏览器地址栏输入想访问的…...

MCU FT61F14x入门
目录 前言一、CMIDE的使用二、系统时钟与睡眠2.1 上电复位 (POR)与系统复位2.2 振荡器和系统时钟2.3 SLEEP睡眠模式 (POWER-DOWN)2.4 低电压检测/比较器 (LVD) 三、I/O端口与中断四、串口USART五、定时器六、ADC七、EEPROM 前言 FT61F14x是辉芒微电子的微控制器,是一…...
星火大模型——多模态API调用(图像+文本)
参考文档 图片理解 API 文档 环境配置 pip3 install websocket-client核心代码 import _thread as thread import base64 import datetime import hashlib import hmac import json from urllib.parse import urlparse import ssl from datetime import datetime from time…...

计算机基础面试题 |22.精选计算机基础面试题
🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…...
kafka连接失败时springboot项目启动停机问题
问题:springboot整合kafka,作为消费端,对端的kafka系统是在生产环境,在本地开发测试时配置了对端的生产环境的kafka地址。因为开发环境和对端生产环境是不通的,所以连接肯定是失败的,kafka的连接失败导致sp…...
【算法题】46. 全排列
题目 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 输入:nums [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 示例 2: 输入࿱…...

可视可交互!在全志H618上用OpenCV读取图像显示到PyQt5窗口上
OpenCV能够处理图像、视频、深度图像等各种类型的视觉数据,在某些情况下,尽管OpenCV可以显示窗口,但PyQt5可能更适合用于创建复杂的交互式应用程序,而自带GPU的H618就成为了这些图像显示的最佳载体。 这里分享一个代码࿰…...
现代密码学 补充1:两种窃听不可区分实验的区别
两种窃听不可区分实验 写在最前面两种窃听不可区分实验1. 完美保密中的窃听不可区分实验2. 窃听不可区分实验(对称加密算法)主要区别 写在最前面 两种窃听不可区分实验 两种窃听不可区分实验(Eavesdropping Indistinguishability Experimen…...

多功能号卡推广分销管理系统 流量卡推广分销网站源码-目前市面上最优雅的号卡系统
一套完善,多功能,的号卡分销系统,多接口,包括运营商接口,无限三级代理,最简单易用的PHP~ 目前市面上最优雅的号卡系统!没有之一 软件架构说明 环境要求php7.3以上(建议低于8.0),MySQL5.6以上,Nginx1.16(无要求) 产品特性 自动安装向导 易于安装使用部署 多个第…...

MySQL语法及IDEA使用MySQL大全
在项目中我们时常需要写SQL语句,或简单的使用注解直接开发,或使用XML进行动态SQL之类的相对困难的SQL,并在IDEA中操控我们的SQL,但网上大都图方便或者觉得太简单了,完全没一个涵盖两个方面的讲解。 单表: …...
分布式系统网关和sentinel
1.网关 作用:网关是给分布式系统进行请求路由分配的服务 功能: 请求路由 请求过滤 请求鉴权 流量控制 统一日志 2.搭建网关(微服务) 2.1依赖、配置文件、启动类 2.2配置路由(id,断言,…...

无法访问Bing网站 - 解决方案
问题 Bing官方网址:https://www.bing.com/ 电脑无法访问Bing网站,但手机等移动设备可以访问Bing网站,此时可尝试以下方案。 以下方案适用于各种系统,如Win/Linux系统。 解决方案 方案1 修改Bing网址为:https://www4…...
Spring Boot 自动装配原理
Java面试题目录 Spring Boot自动装配原理 Spring Boot启动类上的SpringBootApplication注解中包含EnableAutoConfiguration注解,表示开启自动装配。在EnableAutoConfiguration注解中使用Import注解引入AutoConfigurationImportSelector组件,此类中通过S…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

nnUNet V2修改网络——暴力替换网络为UNet++
更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

Android写一个捕获全局异常的工具类
项目开发和实际运行过程中难免会遇到异常发生,系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler,它是Thread的子类(就是package java.lang;里线程的Thread)。本文将利用它将设备信息、报错信息以及错误的发生时间都…...

解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...

【技巧】dify前端源代码修改第一弹-增加tab页
回到目录 【技巧】dify前端源代码修改第一弹-增加tab页 尝试修改dify的前端源代码,在知识库增加一个tab页"HELLO WORLD",完成后的效果如下 [gif01] 1. 前端代码进入调试模式 参考 【部署】win10的wsl环境下启动dify的web前端服务 启动调试…...
标注工具核心架构分析——主窗口的图像显示
🏗️ 标注工具核心架构分析 📋 系统概述 主要有两个核心类,采用经典的 Scene-View 架构模式: 🎯 核心类结构 1. AnnotationScene (QGraphicsScene子类) 主要负责标注场景的管理和交互 🔧 关键函数&…...