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

【JavaEE初阶】多线程(4)

欢迎关注个人主页:逸狼


创造不易,可以点点赞吗~

如有错误,欢迎指出~



目录

线程安全的 第四个原因

代码举例:

分析原因

解决方法

方法1

方法2 

wait(等待)和notify(通知)

wait和sleep区别


线程安全的 第四个原因

内存可见性,引起的线程安全问题

比如: 一个线程修改,另一个线程读取

代码举例:

import java.util.Scanner;public class Demo13 {public static int n=0;public static void main(String[] args) {Thread t1 = new Thread(()->{while(n==0){//啥也不写}System.out.println("t1线程结束循环");});Thread t2 = new Thread(()->{Scanner scanner =new Scanner(System.in);System.out.println("请输入一个整数: ");n= scanner.nextInt();});t1.start();t2.start();}
}

上述代码中通过线程t2将n的值修改成 非0值,按代码逻辑t1应该结束循环了,但实际上循环还在继续...

分析原因

内存可见性问题,本质上是编译器/ JVM对代码进行优化的时候,优化出了bug,如果代码是单线程的,编译器的代码优化一般都是非常准确的,优化之后不会影响到逻辑

但是代码如果是多线程的,编译器的优化就可能出现误判,导致不该优化的地方也给优化了

解决方法

方法1

加上sleep,增加开销,让编译器不启用优化

方法2 

在变量n的前面 加上volatil关键字(volatil 修饰一个变量,提示编译器这个变量是"易变的")

编译器进行上述优化的前提 是编译器认为,针对这个变量的频繁读取,结果都是固定的

但是volatile 只能解决内存可见性问题,不能解决原子性问题(如果两个线程针对同一个变量进行修改,volatile无能为力)

wait(等待)和notify(通知)

多给线程需要控制线程之间 执行某个逻辑的先后顺序,可以使用wait让 后执行的逻辑等待,完成某些逻辑之后 通过notify唤醒对应的wait

通过wait和notify可以解决'线程饿死'问题

  • wait包含 三个操作:解锁和阻塞等待(这两个操作同时进行(在内部已经打包成原子的),阻塞就是为了收到通知),接收到通知后唤醒,并且重新尝试获取锁
  • notify 是通知wait的线程被唤醒(使用 另一个线程调用)

import java.util.Scanner;public class Demo21 {private static Object locker = new Object();public static void main(String[] args) {Thread t1 = new Thread(() -> {synchronized (locker) {System.out.println("t1 wait 之前");try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("t1 wait 之后");}});Thread t2 = new Thread(() -> {System.out.println("t2 notify 之前");Scanner scanner = new Scanner(System.in);scanner.next(); // 此处用户输入啥都行, 主要是通过这个 next, 构造 "阻塞"synchronized (locker) {locker.notify();}System.out.println("t2 notify 之后");});t1.start();t2.start();}
}

 

在多线程中,一个线程加锁,另一个线程加锁是无意义的,不会有任何阻塞效果 

 wait和notify使用之前都需要确保 先加锁(都需要搭配synchronized使用),才能执行

  • wait默认是"死等"(如果没有notify通知,就会一直等待)
  • wait还提供带参数的版本,指定最大时间(如果wait达到了最大的时间,还没有notify,就不会继续等待了,而是直接继续执行)

wait和sleep区别

假如 多个线程都在同一个对象上wait,此时notify 会随机 唤醒其中的一个线程,而notifyAll会唤醒所有等待的线程  ,大部分情况使用notify一个一个唤醒(多次执行notify),目的是 整个程序执行的过程是比较有序的,如果一下全部唤醒,这些被唤醒的线程会 无序的竞争锁

如果 notify 通知时,无线程wait,不会有任何副作用.

相关文章:

【JavaEE初阶】多线程(4)

欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 线程安全的 第四个原因 代码举例: 分析原因 解决方法 方法1 方法2 wait(等待)和notify(通知) wait和sleep区别 线程安全的 第四个原因 内存可见性,引起的线程安全问…...

初识 C++ ( 1 )

引言:大家都说c是c的升级语言。我不懂这句话的含义后来看过解释才懂。 一、面向过程语言和面向对象语言 我们都知道C语言是面向过程语言,而C是面向对象语言,说C和C的区别,也就是在比较面向过程和面向对象的区别。 1.面向过程和面向…...

Python数据分析 Pandas库-初步认识

Python数据分析 Pandas库-初步认识 认识Pandas ​ pandas是一个非常实用的Python工具,我们可以把它想象成一个超级强大的表格处理工具,它比Excel更智能,操作更为简单。pands可以从各种文件格式(CSV、JSON、SQL、Excel&#xff0…...

Flutter问题记录 - 适配Xcode 16和iOS 18

文章目录 前言开发环境问题及解决方案1. Upload Symbols Failed2. type UIApplication does not conform to protocol Launcher3. method does not override any method from its superclass 最后 前言 为了新的镜像功能升级了macOS 15和iOS 18,Xcode也不可避免的需…...

VMware ESXi 7.0U3q macOS Unlocker 集成驱动版更新 OEM BIOS 2.7 支持 Windows Server 2025

VMware ESXi 7.0U3q macOS Unlocker 集成驱动版更新 OEM BIOS 2.7 支持 Windows Server 2025 VMware ESXi 7.0U3q macOS Unlocker & OEM BIOS 2.7 集成网卡驱动和 NVMe 驱动 (集成驱动版) ESXi 7.0U3 标准版集成 Intel 网卡、Realtek USB 网卡 和 NVMe 驱动 请访问原文链…...

大数相乘,大数相加

大数相乘&#xff1a; #include <iostream> #include <vector> #include <string>std::vector<int> multiply(const std::vector<int>& num1, const std::vector<int>& num2) {int n1 num1.size();int n2 num2.size();std::ve…...

Spring Boot配置文件敏感信息加密

一&#xff0c;背景 Spring Boot应用中的数据库、Redis、Nacos、MQ等的用户名、连接地址、密码在配置文件中一般都是明文存储&#xff0c;如果系统被系统攻破或者配置文件所在的目录读权限被破解&#xff0c;又或者是动态配置文件被窃取&#xff0c;内部人员或者黑客很容易通过…...

Java操作数栈分析

Java 的操作数栈&#xff08;Operand Stack&#xff09;是 JVM 的运行时数据区域之一&#xff0c;位于每个线程的栈帧中。操作数栈用于临时存储操作的中间结果和数据&#xff08;操作数&#xff09;&#xff0c;在方法执行时&#xff0c;JVM 的字节码指令会对操作数栈进行操作。…...

C#|.net core 基础 - 值传递 vs 引用传递

不知道你在开发过程中有没有遇到过这样的困惑&#xff1a;这个变量怎么值被改&#xff1f;这个值怎么没变&#xff1f; 今天就来和大家分享可能导致这个问题的根本原因值传递 vs 引用传递。 在此之前我们先回顾两组基本概念&#xff1a; 值类型** vs 引用类型** **值类型&a…...

axure的下载,激活,汉化全过程,多图

1.前言 下载地址&#xff1a;https://pan.baidu.com/s/12xo1mJer2hmBK7QrYM5v-Q?pwd0107#list/path%2Fcsdn%E5%85%B1%E4%BA%AB%E6%96%87%E4%BB%B6 源文章&#xff1a;https://blog.csdn.net/iwanttostudyc/article/details/123773796?ops_request_misc%257B%2522request%25…...

LCR 026

题目&#xff1a;LCR 026 解法一&#xff1a;线性表 将链表中所有元素加入数组中&#xff0c;创建两个指针&#xff0c;分别指向数组的头部和尾部&#xff0c;然后向中间遍历 public void reorderList(ListNode head) {if (head null || head.next null || head.next.next …...

万能小程序运营管理系统 _requestPost 任意文件读取漏洞复现

0x01 产品简介 万能小程序运营管理系统是一种功能全面的系统,旨在帮助开发者和运营人员更好地管理和推广小程序。该系统集成了多种功能模块,覆盖了从小程序开发、部署到运营管理的全链条服务。系统通过提供丰富的功能和工具,帮助用户轻松搭建、管理和优化小程序。该系统支持…...

libyuv之linux编译

文章目录 一、下载源码二、编译源码三、注意事项1、银河麒麟系统&#xff08;aarch64&#xff09;&#xff08;1&#xff09;解决 armv8-adotprodi8mm 指令集支持问题&#xff08;2&#xff09;解决 armv9-asve2 指令集支持问题 一、下载源码 到GitHub网站下载https://github.…...

vue3路由基本使用

在 Vue 3 中&#xff0c;路由指的是应用程序的导航系统&#xff0c;允许你在不同的视图或页面之间进行切换。通过 vue-router 插件&#xff0c;你可以定义路由规则&#xff0c;将 URL 路径映射到 Vue 组件&#xff0c;实现页面间的跳转和状态管理。使用路由&#xff0c;用户可以…...

哪些人适合学习人工智能?

人工智能&#xff08;AI&#xff09;的浪潮正席卷全球&#xff0c;它不仅是科技领域的一场革命&#xff0c;更是社会进步的重要推手。随着AI技术的不断成熟和应用领域的不断拓展&#xff0c;越来越多的人开始关注并渴望掌握这一前沿技术。那么&#xff0c;究竟哪些人适合学习人…...

计算机的错误计算(九十七)

摘要 讨论 的计算精度问题。 由计算机的错误计算&#xff08;九十六&#xff09;知&#xff0c;IEEE754-2019标准中含有 运算。 另外&#xff0c;似乎没有语言直接编程实现内置了该运算。 例1. 已知 x-0.9999999999076 . 计算 不妨用 Python的 math库与 numpy库中的 …...

Flask-Migrate的使用

组织一个 Flask 项目通常需要遵循一定的结构&#xff0c;以便代码清晰、可维护。下面是一个典型的 Flask 项目结构&#xff1a; my_flask_app/ │ ├── app/ │ ├── __init__.py │ ├── models.py │ ├── views.py │ ├── forms.py │ ├── templat…...

python怎么输入整数

使用input()函数输入一个整数&#xff1a; ainput&#xff08;“请输入一个整数\n”&#xff09; 结果却报错TypeError: str object cannot be interpreted as an integer 查阅文档发现input()函数返回值是str型。 我们只需要这样转换&#xff1a; aint(input("请输入一…...

代码随想录打卡Day36

今天做的头皮发麻&#xff0c;除了第一道题是自己AC的&#xff0c;剩下两道题目都是看视频才AC的&#xff0c;主要是看了视频也花了很久时间才想清楚。 1049. 最后一块石头的重量 II 这道题一开始没什么思路&#xff0c;但是看到提示说和昨天的分割子集很像&#xff0c;然后我…...

速盾:凡科建站开cdn了吗?

凡科建站是一家专业的建站平台&#xff0c;提供了多种功能和工具来帮助用户快速搭建自己的网站。随着互联网技术的不断发展&#xff0c;网站的访问速度和稳定性成为了越来越重要的考虑因素。为了优化用户体验&#xff0c;提高网站的加载速度&#xff0c;凡科建站已经开启了CDN&…...

python贪吃蛇游戏项目源码【免费】

使用Pygame库实现的贪吃蛇游戏。Pygame是一个用于创建视频游戏的Python模块集合&#xff0c;它提供了图形和声音库&#xff0c;使游戏开发变得容易。 初始化设置 屏幕大小 (SCREEN_WIDTH, SCREEN_HEIGHT): 定义了游戏窗口的宽度和高度。方格大小 (SIZE): 定义了游戏中每个小方…...

Mycat搭建分库分表

分库分表解决的问题 单表数据量过大带来的性能和存储容量的限制的问题&#xff1a; 索引效率下降读写瓶颈存储容量限制事务性能问题分库分表架构 再搭建一对主从复制节点&#xff0c;3307主节点&#xff0c;3309从节点配置数据源 dw1 , dr1,创建集群c1创建逻辑库 CREATE DATAB…...

Python中的数据结构

1.列表 可以将列表理解为一个购物清单&#xff0c;这个清单里面的的每个元素可以是任何类型&#xff0c;并且可以重复&#xff08;这里区别了列表与数组&#xff09;。列表用“[]”表示。 #这里定义了一个列表&#xff0c;列表中的元素的类型不同。 lsit_a [a, b, c, 1, 2] …...

mysql笔记8(多表查询)

文章目录 1. union联合查询可能会用到去重操作 2. inner join 内连接3. left join 左连接4. right join 右连接5. cross join 交叉连接6. natural join 自然连接natural left join 自然左连接natural right join 自然右连接自然连接的两张表没有同名字段怎么办&#xff1f; 7. …...

typescript-tsconfig文件解释

ts.config.json 作用 用于标识 TypeScript 项目的根路径用于配置 TypeScript 编译器用于指定编译的文件 重要字段 files - 设置要编译的文件的名称&#xff1b;include - 设置需要进行编译的文件&#xff0c;支持路径模式匹配&#xff1b;exclude - 设置无需进行编译的文件…...

所有用贪心的算法和所有用动态规划(dp)的算法合集

贪心 纯贪心算法&#xff08;常在普及组中做暴力题正解使用&#xff09;DijkstraBFS&#xff08;最短路径&#xff09;KruskalPrimSollin&#xff08;Boruvka)二分三分最值排序LCA&#xff08;纯贪心版&#xff09; 动态规划&#xff08;dp&#xff09; Floyd线性DP区间DP背…...

论文阅读 | 基于流模型和可逆噪声层的鲁棒水印框架(AAAI 2023)

Flow-based Robust Watermarking with Invertible Noise Layer for Black-box DistortionsAAAI, 2023&#xff0c;新加坡国立大学&中国科学技术大学本论文提出一种基于流的鲁棒数字水印框架&#xff0c;该框架采用了可逆噪声层来抵御黑盒失真。 一、问题 基于深度神经网络…...

上线跨境电商商城的步骤

上线一个跨境电商商城涉及多个步骤&#xff0c;从前期准备到上线后的维护。以下是一些关键步骤&#xff1a; 1. 市场调研与规划 目标市场分析&#xff1a;研究目标市场的需求、竞争对手和消费者行为。法律法规&#xff1a;了解并遵守目标市场的法律法规&#xff0c;包括税收、…...

Python基础(七)——PyEcharts数据分析(面向对象版)

四、使用PyEcharts数据分析案例&#xff08;面向对象版&#xff09; 【前言&#xff1a;为了巩固之前的Python基础知识&#xff08;一&#xff09;到&#xff08;五&#xff09;&#xff0c;并为后续使用Python作为数据处理的好帮手&#xff0c;我们一起来用面向对象的思想来理…...

滚雪球学SpringCloud[5.1讲]: Spring Cloud Config详解

全文目录&#xff1a; 前言1. Spring Cloud Config的基本概念1.1 微服务配置管理的挑战1.2 Spring Cloud Config的架构 2. 配置服务端与客户端的配置2.1 配置服务端的搭建2.2 配置客户端的搭建2.3 环境隔离配置 3. 配置中心与Git的集成3.1 Git仓库的目录结构设计3.2 配置的版本…...