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

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 中的无锁实现
  1. 原子变量:Java 提供了一些原子类,如 AtomicIntegerAtomicLongAtomicReference,它们通过底层的 CAS 实现来保证原子性。

    AtomicInteger atomicInteger = new AtomicInteger(0);
    atomicInteger.incrementAndGet();  // 原子性递增
    
  2. 自旋锁:通过不断循环检查某个条件来决定是否进入临界区。CAS 属于一种自旋锁。Java 的 ReentrantLock 提供 tryLock 方法来实现非阻塞的加锁逻辑。

  3. 无锁集合:Java 提供了 ConcurrentLinkedQueueConcurrentLinkedDeque 等无锁集合类,这些类基于 CAS 操作设计,支持高并发环境下的操作。

1.3. 无锁编程的优缺点

  • 优点

    • 避免线程阻塞,减少上下文切换。
    • 性能高,适合高并发环境。
  • 缺点

    • 逻辑复杂,CAS 循环可能导致高开销。
    • ABA 问题:CAS 判断时,如果变量的值由 A 变为 B,再变回 A,会误判未变化。Java 使用 AtomicStampedReference 来解决 ABA 问题。

二、锁机制详解和分类

Java 提供了多种锁机制,以 synchronizedReentrantLock 为代表。锁机制分为多种类型,根据其特性可分为以下几类。

2.1 锁的分类
  1. 可重入锁(Reentrant Lock)

    • 概念:允许同一线程在持有锁的情况下多次获得该锁。Java 中的 synchronizedReentrantLock 都是可重入锁。
    • 实现:维护一个计数器记录同一线程重复获得锁的次数,解锁时减少计数,直至计数为零时释放锁。
    • 优点:防止死锁,允许递归调用。
  2. 公平锁和非公平锁

    • 公平锁:多个线程按照请求锁的顺序获得锁。ReentrantLock 可以通过构造函数设置为公平锁。
    • 非公平锁:线程获取锁的顺序不固定,可能出现“插队”,有时提高性能。synchronizedReentrantLock 默认是非公平锁。
    • 优缺点:公平锁保证了请求的顺序,避免了线程饥饿;非公平锁在高并发场景下能减少上下文切换,性能更高。
  3. 独占锁和共享锁

    • 独占锁:一次只能被一个线程持有,synchronizedReentrantLock 是独占锁的典型代表。
    • 共享锁:多个线程可以共享该锁,如 ReadWriteLock,允许多个读线程同时访问,但写线程独占。
    • 使用场景:共享锁适合读多写少的场景,避免独占锁的性能瓶颈。
  4. 悲观锁和乐观锁

    • 悲观锁:认为每次操作都会引起冲突,因此上锁以避免冲突,synchronizedReentrantLock 都是悲观锁。
    • 乐观锁:假设冲突很少发生,因此不加锁,而是通过 CAS 来检测冲突,重试直到成功。这种机制用于无锁编程。
    • 使用场景:乐观锁适用于读多写少的场景,悲观锁适合冲突频繁的场景。
  5. 自旋锁

    • 概念:线程获取锁时不会立即阻塞,而是采用“忙等”方式尝试获取锁。
    • 优点:减少线程挂起和恢复的开销,但会消耗 CPU 资源。
    • 使用场景:适用于锁等待时间短的情况,如 CAS 自旋机制。
2.2 锁的实现示例
  • synchronized:Java 内置关键字,简单易用,具有可重入性。由 JVM 实现,不支持超时。
  • ReentrantLock:是 Java 并发包中更灵活的锁,可以实现公平锁、超时等待、响应中断。
    ReentrantLock lock = new ReentrantLock();
    lock.lock();
    try {// 临界区代码
    } finally {lock.unlock();
    }
    
  • ReadWriteLock:读写锁,读锁共享,写锁独占。ReentrantReadWriteLock 是常用实现。
  • StampedLock:支持乐观读锁的锁,可以提高读多写少场景下的性能。

三、死锁及其避免

死锁是指两个或多个线程相互等待对方释放资源,导致程序无法继续执行。发生死锁的条件包括:

  1. 互斥条件:一个资源一次只能被一个线程占用。
  2. 占有且等待:一个线程在持有资源的同时,仍在请求其他资源。
  3. 不可剥夺:资源不能被强制释放,只能由持有它的线程释放。
  4. 环形等待:多个线程形成一个循环等待链。
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...");}}}
}

这里,method1method2 分别尝试获取 lock1lock2,导致两个线程相互等待对方释放锁,从而产生死锁。

3.2 避免死锁的方法
  1. 破坏环形等待条件:规定获取锁的顺序,避免多个线程在请求资源时形成环。
  2. 使用 tryLock:在等待一段时间后自动放弃,避免长时间等待锁,ReentrantLock 提供了 tryLock() 方法。
    if (lock.tryLock(1000, TimeUnit.MILLISECONDS)) {try {// 临界区代码} finally {lock.unlock();}
    }
    
  3. 避免嵌套锁:尽量减少锁的嵌套,或者统一加锁顺序。
  4. 使用超时机制:设置线程获取资源的等待时间,超时后主动释放锁并重试,避免无限期等待。
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;若不存在&#xff…...

ABC370

## A - Raise Both Hands &#xff08;模拟&#xff09; 题意&#xff1a;输入l&#xff0c;r&#xff0c;如果l1r0输出yes&#xff0c;l0r1输出no&#xff0c;否则输出Invalid 代码&#xff1a; #include<bits/stdc.h> using namespace std; typedef long long ll; vo…...

C语言[求x的y次方]

C语言——求x的y次方 这段 C 代码的目的是从用户输入获取两个整数 x 和 y &#xff0c;然后计算 x 的 y 次幂&#xff08;不过这里有个小错误&#xff0c;实际计算的是 x 的 (y - 1) 次幂&#xff0c;后面会详细说&#xff09;&#xff0c;最后输出结果。 代码如下: #include…...

JavaScript part2

一.前言 前面我们讲了一下js的基础语法&#xff0c;但是这些还是远远不够的&#xff0c;我们要想操作标签&#xff0c;实现一个动态且好看的页面&#xff0c;就得学会BOM和DOM&#xff0c;这些都是浏览器和页面的&#xff0c;这样我们才能实现一个好看的页面 二.BOM对象 BOM…...

HarmonyOS开发 - 本地持久化之实现LocalStorage实例

用户首选项为应用提供Key-Value键值型的数据处理能力&#xff0c;支持应用持久化轻量级数据&#xff0c;并对其修改和查询。数据存储形式为键值对&#xff0c;键的类型为字符串型&#xff0c;值的存储数据类型包括数字型、字符型、布尔型以及这3种类型的数组类型。 说明&#x…...

【C++打怪之路Lv12】-- 模板进阶

#1024程序员节&#xff5c;征文# &#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;重生之我在学Linux&#xff0c;C打怪之路&#xff0c;python从入门到精通&#xff0c;数据结构&#xff0c;C语言&#xff0c;C语言题集&#x1f448; 希望得到您…...

第23周Java主流框架入门-SpringMVC 2.RESTful开发风格

课程笔记&#xff1a;RESTful 开发风格 课程介绍 本节课程介绍 RESTful 开发风格&#xff0c;以及如何在 Spring MVC 中应用这种开发模式。传统 MVC 开发通过 Servlet、JSP 和 Java Bean 实现前后端交互&#xff0c;而 RESTful 开发提供了一种新的理念&#xff0c;更适合现代…...

QT枚举类型转字符串和使用QDebug<<重载输出私有枚举类型

一 将QT自带的枚举类型转换为QString 需要的头文件&#xff1a; #include <QMetaObject> #include <QMetaEnum> 测试代码 const QMetaObject *metaObject &QImage::staticMetaObject;QMetaEnum metaEnum metaObject->enumerator(metaObject->indexOf…...

手机柔性屏全贴合视觉应用

在高科技日新月异的今天&#xff0c;手机柔性显示屏作为智能手机市场的新宠&#xff0c;以其独特的可弯曲、轻薄及高耐用性特性引领着行业潮流。然而&#xff0c;在利用贴合机加工这些先进显示屏的过程中&#xff0c;仍面临着诸多技术挑战。其中&#xff0c;高精度对位、应力控…...

HG-ha/MTools参数详解:--gpu-mode、--onnx-provider、--max-workers配置说明

HG-ha/MTools参数详解&#xff1a;--gpu-mode、--onnx-provider、--max-workers配置说明 1. 开篇&#xff1a;为什么你需要关注这些参数&#xff1f; 如果你正在使用HG-ha/MTools这款强大的桌面工具&#xff0c;可能已经体验过它丰富的功能——从图片处理到AI智能工具&#x…...

实战记录:我是如何解决mmdet3d+mmcv1.6.0环境配置的版本地狱问题

从报错堆栈到完美运行&#xff1a;一个CV工程师的mmdet3d环境配置实战手记 那天下午&#xff0c;当我第17次看到AssertionError: MMCV1.6.0 is used but incompatible这个报错时&#xff0c;咖啡杯已经见了底。作为需要复现2021年某篇重要论文的计算机视觉工程师&#xff0c;我…...

造相-Z-Image完整指南:CPU卸载+VAE分片解码防OOM实战部署

造相-Z-Image完整指南&#xff1a;CPU卸载VAE分片解码防OOM实战部署 想在自己的电脑上跑一个高质量的文生图模型&#xff0c;但总被“爆显存”劝退&#xff1f;特别是用RTX 4090这种顶级显卡&#xff0c;跑大模型、生成高分辨率图片时&#xff0c;显存不足&#xff08;OOM&…...

李慕婉-仙逆-造相Z-Turbo开发笔记:使用Typora撰写高质量的模型使用文档

李慕婉-仙逆-造相Z-Turbo开发笔记&#xff1a;使用Typora撰写高质量的模型使用文档 每次分享一个AI模型或工具&#xff0c;最头疼的往往不是部署和调试&#xff0c;而是写文档。截图怎么贴&#xff1f;代码块怎么排版&#xff1f;结构怎么组织才能让人一目了然&#xff1f;如果…...

OpenCV轮廓检测实战:5种mode参数效果对比与选型指南(附代码)

OpenCV轮廓检测实战&#xff1a;5种mode参数效果对比与选型指南&#xff08;附代码&#xff09; 在计算机视觉项目中&#xff0c;轮廓检测往往是物体识别、形状分析和工业检测的第一步。OpenCV提供的cv2.findContours()函数虽然功能强大&#xff0c;但其mode参数的四种不同选项…...

Vue3 + ECharts实战:5分钟搞定动态数据可视化大屏(附完整代码)

Vue3 ECharts 企业级数据大屏实战&#xff1a;从零构建动态可视化看板 数据可视化已成为现代企业决策的核心工具&#xff0c;而Vue3与ECharts的组合则是实现这一目标的黄金搭档。本文将带你从零开始&#xff0c;构建一个完整的企业级数据大屏解决方案&#xff0c;涵盖实时数据…...

资本狂热背后:OpenClaw引爆的AI智能体狂潮,是真风口还是泡沫?78962

SQLAlchemy是Python中最流行的ORM&#xff08;对象关系映射&#xff09;框架之一&#xff0c;它提供了高效且灵活的数据库操作方式。本文将介绍如何使用SQLAlchemy ORM进行数据库操作。 目录 安装SQLAlchemy 核心概念 连接数据库 定义数据模型 创建数据库表 基本CRUD操作…...

【C语言】register 关键字详解

1. 概述register 关键字用于声明希望频繁使用的变量&#xff0c;并提示编译器尽可能将这些变量存储在寄存器中&#xff0c;以提高访问速度。尽管编译器可能会忽略这个提示&#xff0c;但它仍然是一个有效的优化手段&#xff0c;特别是在性能关键的代码中。1.1 主要目的使用 reg…...

Linux 文件系统目录架构全解析

Linux 文件系统采用树形分层结构&#xff0c;以根目录 / 为起点&#xff0c;所有文件和目录都依附于这一核心节点。这种设计遵循 FHS&#xff08;文件系统层次结构标准&#xff09;&#xff0c;让系统资源管理更清晰、协作更高效。下面我们逐一解析核心目录的作用&#xff1a…...

三层架构+MVP 项目的标准化分层设计

三层架构MVP 项目的标准化分层设计&#xff08;附可视化落地规范&#xff09;结合 MVP 模式的三层架构&#xff0c;核心是**“整体三层架构不变&#xff0c;UI 层内部再按 MVP 拆分”&#xff0c;既保留三层架构的“业务-数据-界面”分离优势&#xff0c;又通过 MVP 解决 UI 层…...