Java高并发理论基础
并发级别
由于临界区的存在,多线程之间的并发必须受到控制。根据控制并发的策略,我们可以把并发的级别分为 阻塞、无饥饿、无障碍、无锁、无等待 几种。
阻塞
一个线程是阻塞的,那么在其他线程释放资源之前,当前线程无法继续执行。当我们使用sychronized关键字或者重入锁时,我们得到的就是阻塞的线程。
sychronized关键字和重入锁(ReentrantLock)都试图在执行后续代码之前,得到临界区的锁,如果得不到,线程就会被挂起等待,直到占有了所需资源为止。
无饥饿
如果线程之间是有优先级的,那么线程调度的时候总是倾向于满足高优先级的线程。即,对于同一个资源的分配,是不公平的。
对于非公平锁,系统允许高优先级的线程插队,这样有可能导致低优先级线程产生饥饿。
如果锁是公平的,按照先来后到的原则,那么饥饿就不会产生。所有线程都有机会执行。
无障碍
无障碍是一种最弱的非阻塞调度(乐观锁)。两个线程无障碍的执行,那么不会因为临界区的问题导致一方被挂起,对于无障碍的线程来说,双方共同修改临界区的资源,如果一方把资源修改坏,会立即对自己所做的修改进行回滚,确保数据安全。
阻塞的控制方式属于悲观策略,无障碍(非阻塞)的调度就是一种乐观策略。
一种可行的无障碍实现可以依赖一个“一致性标记”(版本号或者CAS机制都依赖于这种实现),线程在操作之前,先读取并保存这个标记,在操作完成后,再次读取,检查这个标记是否被更改过,如果两者一致,则说明资源访问没有冲突。如果不一致,则重试操作。
无锁
无锁的并行都是无障碍的。在无锁的情况下,所有的线程都能尝试对临界区进行访问,但不同的是,无锁的并发保证必然有一个线程能够在有限步内完成操作离开临界区。
在无锁的调用中,一个典型的特点是可能会 包含一个无穷循环。在这个循环中,线程会不断尝试修改共享变量。如果没有冲突,修改成功,程序退出,否则继续尝试修改。 但无论如何,无锁的并行总能保证有一个线程是可以胜出的。
如下:

无等待
无锁只要求有一个线程可以在有限步骤内完成操作,而无等待要求所有线程必须在有限步骤内完成。这样就不会引起饥饿问题。如果限制这个步骤的上限,还可以进一步分解为有界无等待和线程数无关的无等待几种。
一种典型的无等待结构是RCU(Read Copy Update).他的基本思想是,对数据的读不加控制,在写数据的时候,先取得原始数据的副本,接着只修改副本数据,修改完成后,在合适的时机写回数据。(COW 写时复制)
Java内存模型(JMM)
JMM的关键技术点都是围绕着多线程的原子性、可见性和有序性来建立的。
原子性
原子性指一个操作是不可中断的。即使在多个线程在一起执行的时候,一个操作一旦开始就不会被其他线程干扰。
可见性
可见性是指当一个线程修改了某一个共享变量的时候,其他线程是否能够立即知道这个修改。
在CPU1和CPU2上各运行一个线程,他们共享变量t,由于编译器优化或者硬件优化的缘故,在CPU1上的线程将变量t缓存到cache或者寄存器中,在这种情况下,CPU2上的线程对共享变量做了修改,CPU1上的线程无法意识到这种改动,依然会读取缓存值。因此,产生了可见性问题。
有序性
有序性问题的原因是程序在执行时,可能会进行指令重排,重排后的指令与原本的顺序未必一致。
串行执行的线程不存在指令重排问题,但是多线程间可能会存在,且是否发生指令重排不可预见。
为什么会发生指令重排
之所以发生指令重排,完全是出于性能考虑。一条指令执行是可以分为很多步骤,如下
- 取址IF
- 译码和取寄存器操作数ID
- 执行或者有效地址计算EX
- 存储器访问MEM
- 写回WB
在CPU实际工作中,汇编指令也需要多个步骤依次执行。由于每个步骤都可能使用不同的硬件来完成,如取址时用到PC寄存器或者存储器。执行时用到ALU(算术逻辑单元)。为了提高性能,发明了流水线技术来执行指令。

可以看出,当第二条指令执行时,指令一并未执行完成,有了流水线,CPU才能真正高效的执行。但是,流水线总是害怕被中断。流水线满载时,性能确实相当不错,但是 一旦中断,所有的硬件设备都会进入一个停顿期,再次满载又需要几个周期。因此,性能损失就很大,所以,必须想办法尽量不让流水线中断。之所以需要指令重排,就是为了尽量减少中断流水线。
示例如下:
执行操作
a = b+c;
d = e-f;
指令重排前执行过程

由于ADD、SUB操作都需要等待上一条指令的结果,因此,在这里插入了不少停顿。通过将LW Rf,f和LW Re,e移动到前面执行即可。因为先加载e和f对程序是没有影响的,既然在Add的时候要停顿一下,那么停顿的时间不如去做点有意义的事情,指令重排后如下:

由此可见,指令重排对于CPU处理性能是十分必要的。
哪些指令不能重排:Happen-Before规则
Java虚拟机和执行系统会对指令进行一定的重排,但是指令重排是有原则的,并非所有的指令都可以随便改变执行位置。以下罗列了一些基本原则:
- 程序顺序原则:一个线程内保证语义的串行性。
- volatile原则:volatile变量的写先于读发生,这保证了volatile变量的可见性(
当一个线程修改volatile变量时,新的值会被立即刷新到主内存中,并且其他线程能够立即看到这个更新) - 锁规则:解锁必然发生在随后的加锁前。
- 传递性:A先于B,B先于C,那么A必然先于C。
- 线程的start()方法先于他的每一个动作。
- 线程的所有操作先于线程的终结(Thread.join())
- 线程的中断先于被中断线程的代码
- 对象的构造函数的执行、结束先于finalize()方法。
相关文章:
Java高并发理论基础
并发级别 由于临界区的存在,多线程之间的并发必须受到控制。根据控制并发的策略,我们可以把并发的级别分为 阻塞、无饥饿、无障碍、无锁、无等待 几种。 阻塞 一个线程是阻塞的,那么在其他线程释放资源之前,当前线程无法继续执…...
Spring事件机制
文章目录 一、Spring事件二、实现Spring事件1、自定义事件2、事件监听器2.1 实现ApplicationListener接口2.2 EventListener2.3 TransactionalEventListener 3、事件发布4、异步使用 三、EventBus1、事件模式2、EventBus三要素3、同步事件3.1 定义事件类3.2 定义事件监听3.3 测…...
vue+canvas音频可视化
1.代码 <template><div class"subGuide"><canvas id"canvas"></canvas><br><audio id"audio" src"./audio.mp3" controls></audio></div> </template><script> export…...
俊昭stm32笔记
stm32——中断优先级 stm32——创建基础工程模板stm32——创建基础工程模板-CSDN博客 stm32——MCU启动方式stm32——MCU启动方式_stm32调试时程序启动方式-CSDN博客 stm32——串口stm32——串口_stm32 串口-CSDN博客 stm32——lcd液晶显示stm32——lcd液晶显示-CSDN博客...
W30-python03-pytest+selenium+allure访问百度网站实例
此篇文章为总结性,将pystest、selenium、allure结合起来 功能如下,web自动化,输入baidu网站,搜索“雷军”、打开网页中第一条内容 pytestsel.py如下: import time import re import allure import pytest from tools…...
如何在 Debian 8 上安装和使用 PostgreSQL 9.4
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 关系型数据库是满足多种需求的数据组织的基石。它们支持从在线购物到火箭发射等各种应用。PostgreSQL 是一种历史悠久但仍然活跃的…...
【微信小程序】微信小程序设置本地背景图片在真机无法显示的解决方案
微信小程序设置本地背景图片在真机无法显示的解决方案 在开发微信小程序时,很多开发者会遇到一个常见的问题:在调试环境中设置本地背景图片可以正常显示,但在真机上却无法显示。本文将详细探讨这一问题的原因,并提供三种解决方案…...
Arthas在线诊断案例实战整理
Arthas - Java 应用诊断利器 Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法…...
使用 XRDP 远程linux主机
一、简介 XRDP是一个开源的远程桌面协议(Remote Desktop Protocol,RDP)服务器,采用的是标准的RDP。 官网地址:https://www.xrdp.org/ github地址: https://github.com/neutrinolabs/xrdp/releases XRDP也是C/S架构&…...
学习小型gpt源码(自用)
数据集构建_哔哩哔哩_bilibili (b站上有一系列课,从数据处理到模型构建和训练使用) 什么是batch? 为什么一个batch内的句子要一样长? 不同batch的长度可以不一样,但是同一个batch内长度一样!…...
@Transactional使用的注意事项
在项目中涉及到CRUD操作时,一般都会在方法上添加该注解,以为加上Transactional,Spring就可以自动帮我们进行事务的开启、提交 有一个很多人都会犯的误区: 将Spring事务与Transactional划上了等号,只要有数据库相关操作…...
快手可灵视频生成大模型全方位测评
快手视频生成大模型“可灵”(Kling),是全球首个真正用户可用的视频生成大模型,自面世以来,凭借其无与伦比的视频生成效果,在全球范围内赢得了用户的热烈追捧与高度评价。截至目前,申请体验其内测…...
【JavaScript】`Map` 数据结构
文章目录 一、Map 的基本概念二、常见操作三、与对象的对比四、实际应用场景 在现代 JavaScript 中,Map 是一种非常重要且强大的数据结构。与传统的对象(Object)不同,Map 允许您使用各种类型的值作为键,不限于字符串或…...
Ubuntu22.04使用NVM安装多版本Node.js和版本切换
Fabric官方目前支持Node.js开发区块链应用,建议使用Node长期支持版本(LTS)。 建议使用NVM安装Node.js,NVM可以帮助我们方便的在Node的不同版本之间进行切换,这样我们就可以同时工作在不同的项目上。 下面是安装的脚本…...
基于C51和OLED12864实现Goole小恐龙
在数字娱乐领域,Google小恐龙(T-Rex Runner)以其简单而上瘾的游戏机制赢得了广泛的关注和喜爱。这款内置于Chrome浏览器的离线小游戏,不仅为用户带来了乐趣,也激发了开发者们对其进行各种创新和扩展的灵感。本文将介绍…...
【Docker】CentOS7环境下的安装
环境展示 安装 配置仓库 sudo yum install -y yum-utils # docker官方key文件下载 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 建议使用阿里云key文件下载 sudo yum-config-manager --add-repo https://mirrors.aliyun.…...
浏览器的最大并发数(http1.1)
HTTP/1.1:每个资源请求通常需要单独的TCP连接,尽管支持Keep-Alive机制,允许在同一个TCP连接上连续发送多个请求。但通常浏览器限制并发TCP连接数(例如,每个域名最多6个并发连接)。 HTTP/2:引入…...
Android 开发中px、dpi 和 dp三个单位的介绍
Android 开发中px、dpi 和 dp三个单位的介绍 在 Android 开发中,px、dpi 和 dp 是用来描述屏幕尺寸和密度的单位,它们在设计和开发中有着不同的作用和用途。 1. px(像素) 定义: px 表示屏幕上的一个像素点,…...
zookeeper开启SASL权限认证
目录 一、SASL介绍 二、使用 SASL 进行身份验证 2.1 服务器到服务器的身份验证 2.2 客户端到服务器身份验证 三、验证功能 一、SASL介绍 默认情况下,ZooKeeper 不使用任何形式的身份验证并允许匿名连接。但是,它支持 Java 身份验证与授权服务(JAAS)…...
mysql一个小问题引发的思考-mysql类型转换-查询缓存 及 MYSQL查询缓存以及自动选择不使用查询缓存的情况
一、mysql一个小问题引发的思考-mysql类型转换-查询缓存 最近在做的一个项目中有一个SQL语句发现点问题,大概如下: select * from table where cid0 or find_in_set(1, cid); 数据表中的字段cid是字符串类型,原来的后端同学未提过此字段还能是…...
别再死记硬背了!用数字电路里的‘上升沿’和‘下降沿’来理解epoll的ET模式(附Linux C++代码演示)
从数字电路到高性能IO:用硬件思维理解epoll的边沿触发模式 当你在示波器上观察一个时钟信号时,工程师们最关心的往往不是电平本身的高低,而是电平跳变的瞬间——那个被称为"边沿"的微妙时刻。这种硬件设计中的经典概念,…...
硬件工程师差旅数据安全与设备防护全攻略
1. 一次旅行噩梦引发的硬件工程师深度思考那次在曼彻斯特机场洗手间里,背包从门上一个简陋的金属挂钩上滑落,发出那声令人心悸的“咔嚓”声时,我脑子里闪过的第一个念头不是“我的电脑完了”,而是“完了,我所有的设计文…...
Android系统安全漏洞深度剖析:从Stagefright到权限提升攻击链
1. 从Stagefright到MediaServer:一场持续的安全风暴2015年的夏天,对于Android生态圈的安全工程师和开发者来说,绝对称得上是一个“多事之秋”。如果你当时正负责某个移动应用的安全审计,或者正在为自家公司的设备进行固件加固&…...
claw-installer:构建自动化部署脚本的工程实践与设计哲学
1. 项目概述与核心价值最近在折腾一个挺有意思的开源项目,叫claw-installer。这名字乍一看有点抽象,但如果你对自动化部署、特别是那些需要处理复杂依赖和配置的应用感兴趣,那这个工具很可能就是你一直在找的“瑞士军刀”。简单来说ÿ…...
微博图片智能采集器:一键构建你的专属视觉素材库
微博图片智能采集器:一键构建你的专属视觉素材库 【免费下载链接】weibo-image-spider 微博图片爬虫,极速下载、高清原图、多种命令、简单实用。 项目地址: https://gitcode.com/gh_mirrors/we/weibo-image-spider 还在为手动保存微博图片而烦恼吗…...
终极指南:3分钟学会用Video-subtitle-extractor高效提取视频硬字幕
终极指南:3分钟学会用Video-subtitle-extractor高效提取视频硬字幕 【免费下载链接】video-subtitle-extractor 视频硬字幕提取,生成srt文件。无需申请第三方API,本地实现文本识别。基于深度学习的视频字幕提取框架,包含字幕区域检…...
Java 注解底层原理、组合注解实现与 AOP 协同机制全解析
Java 注解底层原理与 AOP 协同工作机制 系统性总结 本文严格基于 Java 注解底层原理及 AOP 结合使用的核心技术论述,对知识点进行系统性梳理、重组与优化。全文遵循元注解构建组合注解 → 注解编译与运行底层机制 → 注解AOP 协同工作原理 → 实战问题与解决方案的逻…...
告别Windows桌面混乱:NoFences桌面分区工具终极指南
告别Windows桌面混乱:NoFences桌面分区工具终极指南 【免费下载链接】NoFences 🚧 Open Source Stardock Fences alternative 项目地址: https://gitcode.com/gh_mirrors/no/NoFences 你是否每天都要在堆积如山的桌面图标中寻找需要的应用&#x…...
告别300MB限制!用ZotFile插件+坚果云,打造你的免费Zotero文献同步方案
告别300MB限制!用ZotFile插件坚果云打造高效文献同步方案 在学术研究的日常中,文献管理工具Zotero无疑是许多人的得力助手。然而,免费账户仅有的300MB存储空间,对于需要处理大量PDF文献的研究者来说,往往显得捉襟见肘。…...
从零到跑通:Windows下OTB100数据集与Matlab评测环境保姆级避坑指南
从零到跑通:Windows下OTB100数据集与Matlab评测环境保姆级避坑指南 刚接触目标跟踪领域的研究者,往往需要从经典数据集评测开始。OTB(Object Tracking Benchmark)作为目标跟踪领域的基石数据集,包含100个具有挑战性的视…...
