java的无锁编程和锁机制
Java 的并发编程中,为了保证线程安全和高性能,采用了两种主要的同步手段:锁机制和无锁编程。以下是对锁机制、无锁编程、死锁及其避免的详细讲解。
一、无锁编程
无锁编程通过原子操作来避免传统锁,从而减少线程的上下文切换,提升性能。在 Java 中,通常使用 java.util.concurrent.atomic
包中的类来实现无锁操作。
1.1. 无锁编程的核心:CAS(Compare-And-Swap)
CAS 是无锁编程的核心机制,用来实现原子性更新。CAS 操作有三个参数:
- V:内存地址的变量值
- E:期望值
- N:新值
在进行 CAS 操作时,如果 V == E
,则 V
更新为 N
,如果不相等,表示有其他线程在操作这个值,操作失败。这样实现了原子性更新。
1.2. Java 中的无锁实现
-
原子变量:Java 提供了一些原子类,如
AtomicInteger
、AtomicLong
、AtomicReference
,它们通过底层的 CAS 实现来保证原子性。AtomicInteger atomicInteger = new AtomicInteger(0); atomicInteger.incrementAndGet(); // 原子性递增
-
自旋锁:通过不断循环检查某个条件来决定是否进入临界区。
CAS
属于一种自旋锁。Java 的ReentrantLock
提供tryLock
方法来实现非阻塞的加锁逻辑。 -
无锁集合:Java 提供了
ConcurrentLinkedQueue
、ConcurrentLinkedDeque
等无锁集合类,这些类基于 CAS 操作设计,支持高并发环境下的操作。
1.3. 无锁编程的优缺点
-
优点:
- 避免线程阻塞,减少上下文切换。
- 性能高,适合高并发环境。
-
缺点:
- 逻辑复杂,CAS 循环可能导致高开销。
- ABA 问题:CAS 判断时,如果变量的值由 A 变为 B,再变回 A,会误判未变化。Java 使用
AtomicStampedReference
来解决 ABA 问题。
二、锁机制详解和分类
Java 提供了多种锁机制,以 synchronized
和 ReentrantLock
为代表。锁机制分为多种类型,根据其特性可分为以下几类。
2.1 锁的分类
-
可重入锁(Reentrant Lock)
- 概念:允许同一线程在持有锁的情况下多次获得该锁。Java 中的
synchronized
和ReentrantLock
都是可重入锁。 - 实现:维护一个计数器记录同一线程重复获得锁的次数,解锁时减少计数,直至计数为零时释放锁。
- 优点:防止死锁,允许递归调用。
- 概念:允许同一线程在持有锁的情况下多次获得该锁。Java 中的
-
公平锁和非公平锁
- 公平锁:多个线程按照请求锁的顺序获得锁。
ReentrantLock
可以通过构造函数设置为公平锁。 - 非公平锁:线程获取锁的顺序不固定,可能出现“插队”,有时提高性能。
synchronized
和ReentrantLock
默认是非公平锁。 - 优缺点:公平锁保证了请求的顺序,避免了线程饥饿;非公平锁在高并发场景下能减少上下文切换,性能更高。
- 公平锁:多个线程按照请求锁的顺序获得锁。
-
独占锁和共享锁
- 独占锁:一次只能被一个线程持有,
synchronized
和ReentrantLock
是独占锁的典型代表。 - 共享锁:多个线程可以共享该锁,如
ReadWriteLock
,允许多个读线程同时访问,但写线程独占。 - 使用场景:共享锁适合读多写少的场景,避免独占锁的性能瓶颈。
- 独占锁:一次只能被一个线程持有,
-
悲观锁和乐观锁
- 悲观锁:认为每次操作都会引起冲突,因此上锁以避免冲突,
synchronized
和ReentrantLock
都是悲观锁。 - 乐观锁:假设冲突很少发生,因此不加锁,而是通过 CAS 来检测冲突,重试直到成功。这种机制用于无锁编程。
- 使用场景:乐观锁适用于读多写少的场景,悲观锁适合冲突频繁的场景。
- 悲观锁:认为每次操作都会引起冲突,因此上锁以避免冲突,
-
自旋锁
- 概念:线程获取锁时不会立即阻塞,而是采用“忙等”方式尝试获取锁。
- 优点:减少线程挂起和恢复的开销,但会消耗 CPU 资源。
- 使用场景:适用于锁等待时间短的情况,如 CAS 自旋机制。
2.2 锁的实现示例
synchronized
:Java 内置关键字,简单易用,具有可重入性。由 JVM 实现,不支持超时。ReentrantLock
:是 Java 并发包中更灵活的锁,可以实现公平锁、超时等待、响应中断。ReentrantLock lock = new ReentrantLock(); lock.lock(); try {// 临界区代码 } finally {lock.unlock(); }
ReadWriteLock
:读写锁,读锁共享,写锁独占。ReentrantReadWriteLock
是常用实现。StampedLock
:支持乐观读锁的锁,可以提高读多写少场景下的性能。
三、死锁及其避免
死锁是指两个或多个线程相互等待对方释放资源,导致程序无法继续执行。发生死锁的条件包括:
- 互斥条件:一个资源一次只能被一个线程占用。
- 占有且等待:一个线程在持有资源的同时,仍在请求其他资源。
- 不可剥夺:资源不能被强制释放,只能由持有它的线程释放。
- 环形等待:多个线程形成一个循环等待链。
3.1 死锁示例
以下代码展示了两个线程死锁的情况:
class DeadlockDemo {private final Object lock1 = new Object();private final Object lock2 = new Object();public void method1() {synchronized (lock1) {System.out.println("Thread 1: Holding lock 1...");try { Thread.sleep(10); } catch (InterruptedException e) {}synchronized (lock2) {System.out.println("Thread 1: Holding lock 2...");}}}public void method2() {synchronized (lock2) {System.out.println("Thread 2: Holding lock 2...");try { Thread.sleep(10); } catch (InterruptedException e) {}synchronized (lock1) {System.out.println("Thread 2: Holding lock 1...");}}}
}
这里,method1
和 method2
分别尝试获取 lock1
和 lock2
,导致两个线程相互等待对方释放锁,从而产生死锁。
3.2 避免死锁的方法
- 破坏环形等待条件:规定获取锁的顺序,避免多个线程在请求资源时形成环。
- 使用
tryLock
:在等待一段时间后自动放弃,避免长时间等待锁,ReentrantLock
提供了tryLock()
方法。if (lock.tryLock(1000, TimeUnit.MILLISECONDS)) {try {// 临界区代码} finally {lock.unlock();} }
- 避免嵌套锁:尽量减少锁的嵌套,或者统一加锁顺序。
- 使用超时机制:设置线程获取资源的等待时间,超时后主动释放锁并重试,避免无限期等待。
3.3 死锁检测工具
JVM 提供了 jstack
工具,可以用于分析线程堆栈信息,检查是否发生死锁。
相关文章:
java的无锁编程和锁机制
Java 的并发编程中,为了保证线程安全和高性能,采用了两种主要的同步手段:锁机制和无锁编程。以下是对锁机制、无锁编程、死锁及其避免的详细讲解。 一、无锁编程 无锁编程通过原子操作来避免传统锁,从而减少线程的上下文切换&am…...
vue实现富文本编辑器上传(粘贴)图片 + 文字
vue实现富文本编辑器上传(粘贴)图片 文字 1.安装插件 npm install vue-quill-editor -s2.在使用vue-quill-editor富文本的时候,对于图片的处理经常是将图片转换成base64,再上传数据库,但是base64不好存储。 原理&a…...
子集和全排列(深度优先遍历)问题
欢迎访问杀马特主页:小小杀马特主页呀! 目录 前言: 例题一全排列: 1.题目介绍: 2.思路汇总: 3.代码解答: 例题二子集: 题目叙述: 解法一: 1.思路汇总…...
判断检测框是否在感兴趣区域(ROI)内
判断检测框是否在感兴趣区域(ROI)内 在计算机视觉和图像处理中,我们经常需要确定一个矩形检测框是否位于一个特定的感兴趣区域(Region of Interest, ROI)内。这个ROI可以是一个多边形,而检测框则是一个矩形…...
正点原子阿尔法ARM开发板-IMX6ULL(九)——关于SecureCRT连接板子上的ubuntu
文章目录 一、拨码器二、SecureCRT 一、拨码器 emmm,也是好久没学IMX6ULL了,也是忘了拨码器决定了主板的启动方式 一种是直接从TF卡中读取文件(注意这里是通过imdownload软件编译好了之后,通过指令放入TF卡) 一种是现在这种用串口…...
微信支付Java+uniapp微信小程序
JS: request.post(/vip/pay, {//这是自己写的java支付接口id: this.vipInfo.id,payWay: wechat-mini}).then((res) > {let success (res2) > {//前端的支付成功回调函数this.$refs.popup.close();// 支付成功刷新当前页面setTimeout(() > {this.doGetVipI…...
【NOIP提高组】加分二叉树
【NOIP提高组】加分二叉树 💐The Begin💐点点关注,收藏不迷路💐 设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为节点编号。每个节点都有一个分数(均为正整…...
HarmonyOS 相对布局(RelativeContainer)
1. HarmonyOS 相对布局(RelativeContainer) 文档中心:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-layout-development-relative-layout-V5 RelativeContainer为采用相对布局的容器,支持容器内部的子元素设…...
webpack5搭建react脚手架详细步骤
1. 初始化项目 首先,创建一个新目录并初始化项目: bash mkdir create-react cd create-react pnpm init --y git init 这里使用pnpm作为包管理工具,因为它在处理依赖和速度上表现更好。 2. 安装React和TypeScript 安装React和React-DOM…...
速盾:高防cdn怎么拦截恶意ip?
高防CDN(Content Delivery Network)是一种用于防御网络攻击和提供高可用性的服务。它通过分发网络流量,将用户的请求导向最近的服务器,从而提高网站的加载速度和稳定性。然而,不可避免地,有些恶意IP地址会试…...
太阳能面板分割系统:训练自动化
太阳能面板分割系统源码&数据集分享 [yolov8-seg-EfficientHead&yolov8-seg-vanillanet等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Globa…...
C++笔记---位图
1. 位图的概念 位图(Bitmap)是一种基于位操作的数据结构,用于表示一组元素的集合信息。它通常是一个仅包含0和1的数组,每个元素对应一个二进制位,若该元素存在,则对应的位为1;若不存在ÿ…...
ABC370
## A - Raise Both Hands (模拟) 题意:输入l,r,如果l1r0输出yes,l0r1输出no,否则输出Invalid 代码: #include<bits/stdc.h> using namespace std; typedef long long ll; vo…...
C语言[求x的y次方]
C语言——求x的y次方 这段 C 代码的目的是从用户输入获取两个整数 x 和 y ,然后计算 x 的 y 次幂(不过这里有个小错误,实际计算的是 x 的 (y - 1) 次幂,后面会详细说),最后输出结果。 代码如下: #include…...
JavaScript part2
一.前言 前面我们讲了一下js的基础语法,但是这些还是远远不够的,我们要想操作标签,实现一个动态且好看的页面,就得学会BOM和DOM,这些都是浏览器和页面的,这样我们才能实现一个好看的页面 二.BOM对象 BOM…...
HarmonyOS开发 - 本地持久化之实现LocalStorage实例
用户首选项为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。数据存储形式为键值对,键的类型为字符串型,值的存储数据类型包括数字型、字符型、布尔型以及这3种类型的数组类型。 说明&#x…...
【C++打怪之路Lv12】-- 模板进阶
#1024程序员节|征文# 🌈 个人主页:白子寰 🔥 分类专栏:重生之我在学Linux,C打怪之路,python从入门到精通,数据结构,C语言,C语言题集👈 希望得到您…...
第23周Java主流框架入门-SpringMVC 2.RESTful开发风格
课程笔记:RESTful 开发风格 课程介绍 本节课程介绍 RESTful 开发风格,以及如何在 Spring MVC 中应用这种开发模式。传统 MVC 开发通过 Servlet、JSP 和 Java Bean 实现前后端交互,而 RESTful 开发提供了一种新的理念,更适合现代…...
QT枚举类型转字符串和使用QDebug<<重载输出私有枚举类型
一 将QT自带的枚举类型转换为QString 需要的头文件: #include <QMetaObject> #include <QMetaEnum> 测试代码 const QMetaObject *metaObject &QImage::staticMetaObject;QMetaEnum metaEnum metaObject->enumerator(metaObject->indexOf…...
手机柔性屏全贴合视觉应用
在高科技日新月异的今天,手机柔性显示屏作为智能手机市场的新宠,以其独特的可弯曲、轻薄及高耐用性特性引领着行业潮流。然而,在利用贴合机加工这些先进显示屏的过程中,仍面临着诸多技术挑战。其中,高精度对位、应力控…...
《Python游戏编程入门》注-第3章3
《Python游戏编程入门》的“3.2.4 Mad Lib”中介绍了一个名为“Mad Lib”游戏的编写方法。 1 游戏玩法 “Mad Lib”游戏由玩家根据提示输入一些信息,例如男人姓名、女人姓名、喜欢的食物以及太空船的名字等。游戏根据玩家输入的信息编写出一个故事,如图…...
Netty-TCP服务端粘包、拆包问题(两种格式)
前言 最近公司搞了个小业务,需要使用TCP协议,我这边负责服务端。客户端是某个设备,客户端传参格式、包头包尾等都是固定的,不可改变,而且还有个蓝牙传感器,透传数据到这个设备,然后通过这个设备…...
centos安装指定版本的jenkins
打开jenkins镜像包官网,找到自己想要安装的版本,官网地址:https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable 下载指定版本安装包: wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/jenkins-2.452.…...
QT 周期性的杀死一个进程(软件),一分钟后自动退出
1.原因:某软件开机自启动很烦,搞一个程序干掉这个自启动的软件 2.QT代码 main.cpp #include "KillXXX.h" #include <QtWidgets/QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);KillXXX k;return a.exec…...
MySQL任意版本安装卸载和数据库原理图绘制
MYSQL任意版本安装和卸载 安装: 1、解压文件 --- 不能出现中文路径 2、在解压目录(安装目录)下: 1>.创建data文件夹 2>.创建配置文件my.txt 然后修改成ini格式 3、修改配置文件 basedirD:\\mysql\\mysql-5.7.28-winx64…...
技术成神之路:设计模式(二十三)解释器模式
相关文章:技术成神之路:二十三种设计模式(导航页) 介绍 解释器模式(Interpreter Pattern)是一种行为设计模式,用于定义一种语言的文法表示,并提供一个解释器来处理这种文法。它用于处理具有特定语法或表达…...
2024软考《软件设计师》-Python专题知识(含历年真题解析)
自2020年之后,软考软件设计师考试在综合知识部分开始增加Python编程语言相关考点,每年会考2~3分的样子。本文将结合近几年常考的内容,扩展一下Pyhton的基础知识!考前看一看,或许有所帮助。 一、基础语法 标识符 第一…...
基于大数据 Python+Vue 旅游推荐可视化系统(源码+LW+部署讲解+数据库+ppt)
!!!!!!!!! 会持续一直更新下去 有问必答 一键收藏关注不迷路 源码获取:https://pan.baidu.com/s/1aRpOv3f2sdtVYOogQjb8jg?pwdjf1d 提取码: jf1d &#…...
使用虚拟机搭建环境:CentOS7 Docker、MySQL、Redis 安装与配置
创作灵感 项目实践总结:记录了在虚拟机中安装与配置CentOS7环境下的Docker、MySQL、Redis的全过程,帮助理解和应用各项技术。技术笔记与问题总结:详细梳理了每一步安装的关键点与常见问题,并给出了解决方案。职业感悟与心得&…...
[分享] Docker容器可视化管理工具 - WGCLOUD
WGCLOUD是新一代运维监测平台,它可以监控Docker容器的各种性能数据,比如内存,cpu,Image,运行时间,运行状态,端口映射等信息 WGCLOUD也支持在页面启动,重启,停止Docker容…...
万网建网站流程/东莞seo广告宣传
此环境搭建是OpenCV的python(一下简称py)开发环境搭建,建立在py3的环境和语法上实现的。 windows系统搭建 系统环境:windows 10 python 3.6 OpenCV 3.4.1 一、安装python python的安装之前在python自学笔记的项目中描述了&…...
济宁医院网站建设/站长工具seo优化建议
NewPan 贝聊科技 iOS 菜鸟工程师这款为天猫定制的 iPhone,你买了吗?由于没摸过真机,所以严格意义上来说,这篇文章应该有一个更加接地气的名字:“模拟器适配实战”。01.适配原则 由于这篇文章是实战,就不巴拉…...
快速做网站服务好/深圳网络营销渠道
数据库批处理 批处理(batch)指的是一次操作中执行多条SQL语句,批处理相比于一次一次执行效率会提高很多。 批处理操作数据库的过程主要是分两步: 将要执行的SQL语句保存执行保存的SQL语句 如何实现批处理 Statement和PreparedStatement都支持批处理操…...
一定seo自己网站吗/域名注册
重心放在大目标上面,长远目标,不要为了短期的,眼前的利益所诱惑。 同时要将功能的学习放在重点,比如字符处理。转载于:https://www.cnblogs.com/daishuguang/archive/2013/05/05/3061552.html...
wordpress无法添加小工具/整站优化价格
GPIO外部中断 文章目录 GPIO外部中断1、GPIO中断介绍2、GPIO中断使用步骤3、软件准备4、硬件准备5、代码实现在前面的文章 ESP32设备驱动-GPIO数字输入与输出中介绍如何对GPIO进行控制操作。本文将在该基础上使用GPIO中断进一步优化按键输入。即演示如何使用GPIO中断。 1、GPI…...
建设网站 报告/如何查询百度收录情况
以下代码没有严格测试,能用,参数的地方有些错误,没有修正,自个看看代码中打开文件如果要用OpenFileDialog需要首先设置main的线程模式,缺点是弹出的对话框居然跑到后面去了,每什么意思。,我现在…...