线程休眠、线程让步、线程优先级相关内容学习笔记
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…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
