Java学习笔记(23)
多线程


并发
并行

多线程实现方式

1.继承Thread类
自己创建一个类extends thread类
Start方法开启线程,自动执行重写之后的run方法


2.实现runable接口
自己创建一个类implements runnable

Myrun不能直接使用getname方法,因为这个方法是thread类的方法
所以需要得到当前线程的thread对象,再用getname方法

3.用callable接口和future接口方法
抽象方法run没有返回值,获取不了运行结果
实现callable接口
重写call方法
Future接口不能直接用,要用他的实现类futuretask管理线程运行结果



Thread的方法

Getname
没有起名,有默认名字:Thread-0,Thread-1.。。
Setname
设置线程名字,可以用set,也可以用构造方法,但是构造方法不能继承,要自己重新写个构造方法,通过super继承父类的构造方法


CurrentThread

Sleep 静态方法 用Thread.sleep调用

抢占式调度
随机
优先级最高10,最小1,默认5
Setpriority(int)
Getpriority

守护线程
SetDaemon(true)
非守护和守护默认没有优先级之分
非守护结束,守护慢慢就也会结束

出让线程
Thread.yield()
让结果每一个线程尽可能均匀运行
插入线程

线程的生命周期
有执行资格:有资格去抢CPU的执行权
没有执行权:还没抢到执行权,不能执行代码

线程安全

Ticket要用static修饰,这样所有这个类的对象就可以共享ticket


为什么会出现这个问题?

执行代码时,线程随时都会被其他线程抢夺执行权
如何解决?
同步代码块
让一个线程执行完完整的一次同步代码块里的代码,才可以重新抢夺执行权

Synchronized(锁对象){}
锁对象:是任意的,但是一定是唯一的,前面用static修饰

锁对象可以是本类的字节码文件

同步方法
如果想把一个方法里面所有的代码都锁起来,就不需要同步代码块
直接将synchronized加在方法上

用runable的时候,由于只需要创建一次,所以里面的ticket就可以不用static修饰

Stringbuffer用于多线程环境,里面的方法和stringbuilder一样的
Lock锁
是一个接口,创建对象要用实现类reentrantlock



以上代码可能出现的问题:
- 如果lock没有用static修饰
则会所有的线程都会创建一个lock,重复ticket,超出范围的问题又会出现,所以要加static修饰,即所有线程共享一个lock,就能解决

2.程序不停止?
没有执行lock.unlock()方法,有线程一直停留在lock.lock()方法,所以程序没有停止
如何避免?
把unlock写到finally中,保证unlock一定会执行

死锁
不要让两个锁嵌套起来写,这样程序就运行不下去

生产者和消费者
等待唤醒机制
生产者:生产数据
消费者:消费数据
消费者等待

生产者等待

完整机制

方法
Wait
一般用notifyall
这几个方法要通过锁对象来进行调用

重写run方法的套路

Desk

Foodie

Cookie

测试类


第二种实现方式:阻塞队列方式
- 数组,有界
- 链表,无界


生产者和消费者要使用同一个阻塞队列
不需要在写锁对象,因为put和take方法的底层就已经有锁了
Take有返回值,类型和put进去的数据一样


线程的状态

Java没有定义运行状态,只有剩下的六种状态
为什么没有?
因为线程抢到CPU的执行权之后,当前线程就会交给操作系统管理,虚拟机就不会再管这个线程了


package exericise;public class exercise1 {public static void main(String[] args) {window t1 = new window();window t2 = new window();t1.setName("窗口1");t2.setName("窗口2");t1.start();t2.start();}
}package exericise;public class window extends Thread{static int ticket =1000;@Overridepublic void run() {while (true) {synchronized (exercise1.class){if (ticket != 0){ticket--;try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(getName() + "还有"+ticket+"张票");}else {break;}}}}
}

package exericise;public class exercise2 {public static void main(String[] args) {Person t1 = new Person();Person t2 = new Person();t1.setName("Person1");t2.setName("Person2");t1.start();t2.start();}
}package exericise;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Person extends Thread {static int gift = 1000;static Lock lock = new ReentrantLock();@Overridepublic void run() {while (true) {lock.lock();try {if (!(gift < 10)) {System.out.println(getName() + "送出第" + gift + "个礼物");gift--;} else {break;}} catch (Exception e) {throw new RuntimeException(e);} finally {lock.unlock();}}}
}

package exericise;public class exercise3 {public static void main(String[] args) {Number t1 = new Number();Number t2 = new Number();t1.setName("线程1");t2.setName("线程2");t1.start();t2.start();}
}package exericise;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Number extends Thread{static int start = 1;static int end = 100;static Lock lock = new ReentrantLock();@Overridepublic void run() {while (true) {lock.lock();try {if (start <= end) {//判断是不是奇数if (start %2 == 1) {//是就打印System.out.println(getName() + ":" + start);}start++;}else {//超过范围break;}} catch (Exception e) {throw new RuntimeException(e);} finally {lock.unlock();}}}
}

package exericise;import java.util.Arrays;
import java.util.Random;public class exercise4 {public static void main(String[] args) {//随机分成3个红包Random r = new Random();for (int i = 0; i < redBao.arr.length; i++) {if (i == redBao.arr.length - 1) {redBao.arr[i] = redBao.redPocket;}else {redBao.arr[i] = r.nextDouble(0.01,redBao.redPocket);redBao.redPocket -= redBao.arr[i];}}System.out.println(Arrays.toString(redBao.arr));redBao rb1 = new redBao();redBao rb2 = new redBao();redBao rb3 = new redBao();redBao rb4 = new redBao();redBao rb5 = new redBao();rb1.setName("No.1");rb2.setName("No.2");rb3.setName("No.3");rb4.setName("No.4");rb5.setName("No.5");rb1.start();rb2.start();rb3.start();rb4.start();rb5.start();}
}
package exericise;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class redBao extends Thread{static double redPocket = 100;//标记是否已经抢到过boolean flag = false;static double[] arr = new double[3];static Lock lock = new ReentrantLock();static int index = 0;static int end = 1;@Overridepublic void run() {lock.lock();try {if (!flag && index <= 2){//还没抢到过红包System.out.println(getName() + "抢到了" + arr[index] + "块钱");index++;flag = true;}if (end >3) {System.out.println(getName() + "没抢到");}end++;} catch (Exception e) {throw new RuntimeException(e);} finally {lock.unlock();}}
}
在run方法中定义一个集合,则所有的进程都会在自己的栈中的run方法里创建出自己的集合,这个集合在不同的进程中独立,互不影响
注意:其实每一个线程都会有自己独立的栈,包括main,里面创建的元素互不影响(除非是static)

线程池

创建线程浪费时间
用完直接丢弃,浪费资源
原理


一般不会关闭线程池:因为服务器24小时都会运行,所以随时都会新任务进来,所以一般不会关闭线程池

Submit:提交任务
Shutdown:销毁线程池
0
自定义线程池
什么时候创建临时线程?
核心线程已被占用,而且排队队伍已满,这是才创建临时线程
先提交的任务,不一定先执行
如图,任务4 5 6在排队,临时线程处理任务7 8

当提交的任务数量大于核心线程数+临时线程数+队伍长度,剩下的任务10就会触发任务拒绝策略


自定义线程池,设置七个参数

ThreadPoolExecutor


到底怎么设置才合适?
最大并行数
系统处理器的线程数,4核8线程,8就是最大并行数
CPU密集型运算:读取文件较少,计算数据较多
为什么+1:如果前面的线程出问题,则多出来的线程就可以顶上,不浪费cpu的时钟周期不被浪费

IO密集性运算:现在的项目大多都是IO密集性的,读取服务器文件操作多
怎么得到计算时间?
通过thread dump的工具来测试计算时间

相关文章:
Java学习笔记(23)
多线程 并发 并行 多线程实现方式 1.继承Thread类 自己创建一个类extends thread类 Start方法开启线程,自动执行重写之后的run方法 2.实现runable接口 自己创建一个类implements runnable Myrun不能直接使用getname方法,因为这个方法是thread类的方法…...
nodejs下载安装以及npm、yarn安装及配置教程
1、nodejs下载安装 1.1、使用nodejs版本管理工具下载安装,可一键安装、切换不同nodejs版本, nvm-setup.zip:安装版,推荐使用 本次演示的是安装版。 1、双击安装文件 nvm-setup.exe 选择nvm安装路径 例如:E:\Soft…...
Playwright库page.evaluate()方法执行JavaScript 表达式
page.evaluate() 方法是 Playwright 中常用的方法之一,用于在页面上下文中执行 JavaScript 代码。它允许在浏览器环境中执行各种操作,如操作 DOM 元素、获取页面数据、执行复杂的计算等,并将结果返回到 Node.js 或 Python 代码中。 在 Playw…...
【微服务】OpenFeign+Sentinel集中处理远程调用异常
文章目录 1.微服务基本环境调整1.对10004模块的application.yml调整2.启动nacos以及一个消费者两个提供者3.测试1.输入http://localhost:8848/nacos/index.html 来查看注册情况2.浏览器访问 http://localhost:81/member/nacos/consumer/get/13.结果 2.使用OpenFeign实现微服务模…...
集合嵌套,Collections,斗地主案例,日志框架
文章目录 集合嵌套List嵌套ListList嵌套MapMap嵌套Map Collections类方法排序 sort 乱序 shuffle 斗地主案例需求思路代码 日志框架介绍优势体系结构Logback概述快速入门配置详解 集合嵌套 List嵌套List public static void main(String[] args){//一个年级有许多班级…...
maven pom relativePath属性的作用
maven pom relativePath属性的作用 文章目录 maven pom relativePath属性的作用一、relativePath出现的地方二、relativePath默认值三、四、<relativePath>一个pom路径 一、relativePath出现的地方 搭建maven项目,子模块指定父模块试,经常会在par…...
【STM32 HAL库SPI/QSPI协议学习,基于外部Flash读取。】
1、SPI协议 简介 SPI 协议是由摩托罗拉公司提出的通讯协议 (Serial Peripheral Interface),即串行外围设备接口,是 一种高速全双工的通信总线。它被广泛地使用在 ADC、LCD 等设备与 MCU 间,要求通讯速率 较高的场合。 SPI 物理层 SPI 通讯…...
Nginx入门--初识Nginx的架构
一、概述 Nginx的架构设计旨在高效处理并发的网络请求。它采用了事件驱动的、非阻塞的IO模型,可以同时处理成千上万个并发连接,而不会消耗太多的系统资源。 二、主要组件 Nginx的主要组件包括: Master Process(主进程…...
网络性能提升10%,ZStack Edge 云原生超融合基于第四代英特尔®至强®可扩展处理器解决方案发布
随着业务模式的逐渐转变、业务架构逐渐变得复杂,同时容器技术的兴起和逐渐成熟,使得Kubernetes、微服务等新潮技术逐步应用于业务应用系统上。 为了充分释放性能、为业务系统提供更高效的运行环境,ZStack Edge 云原生超融合采用了第四代英特尔…...
双非计算机考研目标211,选11408还是22408更稳?
求稳得话,11408比22408要稳! 很多同学只知道,11408和22408在考察的科目上有区别,比如: 11408考的是考研数学一和英语一,22408考察的是考研数学二和英语二: 考研数学一和考研数学二的区别大吗…...
简单了解策略模式
什么是策略模式? 策略模式提供生成某一种产品的不同方式 Strategy策略类定义了某个各种算法的公共方法,不同的算法类通过继承Strategy策略类,实现自己的算法 Context的作用是减少客户端和Strategy策略类之间的耦合,客户端只需要…...
算法——运动模型
智能驾驶中常用的速度计算算法包括基于GPS的速度计算、惯性测量单元(IMU)的速度计算、雷达测距的速度计算、视觉测距的速度计算等。这些算法可以单独使用或者结合使用,以提高速度计算的准确性和稳定性。 智能驾驶中常用的加速度计算算法包括…...
基于R语言lavaan结构方程模型(SEM)技术应用
结构方程模型(Sructural Equation Modeling,SEM)是分析系统内变量间的相互关系的利器,可通过图形化方式清晰展示系统中多变量因果关系网,具有强大的数据分析功能和广泛的适用性,是近年来生态、进化、环境、…...
本地虚拟机服务器修改站点根目录并使用域名访问的简单示例
说明:本文提及效果是使用vmware虚拟机,镜像文件是Rocky8.6 一、配置文件路径 1. /etc/httpd/conf/httpd.conf #主配置文件 2. /etc/httpd/conf.d/*.conf #调用配置文件 调用配置文件的使用: vim /etc/httpd/conf.d/webpage.conf 因为在主配…...
生信数据分析——GO+KEGG富集分析
生信数据分析——GOKEGG富集分析 目录 生信数据分析——GOKEGG富集分析1. 富集分析基础知识2. GO富集分析(Rstudio)3. KEGG富集分析(Rstudio) 1. 富集分析基础知识 1.1 为什么要做功能富集分析? 转录组学数据得到的基…...
微服务(基础篇-007-RabbitMQ)
目录 初识MQ(1) 同步通讯(1.1) 异步通讯(1.2) MQ常见框架(1.3) RabbitMQ快速入门(2) RabbitMQ概述和安装(2.1) 常见消息模型(2.2) 快速入门ÿ…...
汇总:五个开源的Three.js项目
Three.js 是一个基于 WebGL 的 JavaScript 库,它提供了一套易于使用的 API 用来在浏览器中创建和显示 3D 图形。通过抽象和简化 WebGL 的复杂性,Three.js 使开发者无需深入了解 WebGL 的详细技术就能够轻松构建和渲染3D场景、模型、动画、粒子系统等。 T…...
JavaScript(一)---【js的两种导入方式、全局作用域、函数作用域、块作用域】
一.JavaScript介绍 1.1什么是JavaScript JavaScript简称“js”,js与java没有任何关系。 js是一种“轻量级、解释型、面向对象的脚本语言”。 二.JavaScript的两种导入方式 2.1内联式 在HTML文档中使用<script>标签直接引用。 <script>console.log…...
部署云原生边缘计算平台kubeedge
文章目录 1、kubeedge架构2、基础服务提供 负载均衡器 metallb2.1、开启ipvc模式中的strictARP2.2、部署metalb2.2.1、创建IP地址池2.2.2、开启二层转发,实现在k8s集群节点外访问2.2.3、测试 3、部署cloudcore3.1、部署cloudcore3.2、修改cloudcore的网络类型 4、部…...
Java设计模式:单例模式详解
设计模式:单例详解 文章目录 设计模式:单例详解一、单例模式的原理二、单例模式的实现推荐1、饿汉模式2、静态内部类 三、单例模式的案例四、单例模式的使用场景推荐总结 一、单例模式的原理 单例模式听起来很高大上,但其实它的核心思想很简…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
