JAVA内存模式-5-锁

锁升级过程(无锁、偏向锁、轻量级锁、重量级锁) synchronized锁升级:无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁 阅读详情

从happens-before角度来看锁的释放-获取

跟volatile一样

锁的释放-获取的内存过程

跟volatile一样

如何实现锁的内存效果??

作者这里以ReentrantLock为案例进行讲解。

Java同步器框架AbstractQueuedSynchronizer,这里暂时简称为AQS。

做讲解ReentrantLock时作者分为公平锁、非公平锁,这里我再做详解:

ReentrantLock公平锁

获取锁:

释放锁:

公平锁lock时,首先读volatile变量、

公平锁unlock时,最后写volatile变量。

这里的意思是:A线程unlock时,volatile前面的StoreStore确保把之前修改的结果刷新到主内存,然后对其他线程内存可见,然后再通过StoreLoad结束。

A线程结束后,通知B线程。

B线程lock时,通过LoadLoad把A线程修改的结果放到CPU缓冲区里,然后再通过LoadStore指令执行lock后面的代码,直到运行到unlock为止,依次轮退。

ReentrantLock非公平锁

非公平锁的释放与公平锁完全一致,区别在于非公平锁的获取:

非公平锁的获取是通过sun.misc.Unsafe.compareAndSwapInt()方法获取,而该方法最后还是调用unsafe.cpp/atomic.cpp/atomic_windows
_x86.inline.hpp。(这里是针对windows操作系统x86处理器,不同操作系统不同处理器调用不同的hpp等。)

这里CPU如果是多核的话,会添加lock前缀,单核的就不添加(单核自己负责顺序一致性),而intel对lock前缀的解释是:

  1. 确保该前缀对内存的读-改-写操作原子执行。早期CPU处理lock执行期间会锁住内存总线导致其他CPU均无法通过内存总线访问主内存,由于代价太高,后来优化为:如果要访问的主内存区域在lock前缀指令执行期间已经在处理器内部的缓存中被锁定(即包含该内存区域的缓存行当前处于独占或者已修改状态)、并且该内存区域被完全包含在单个缓存行中,那么处理器将直接执行该指令。由于在指令执行期间该缓存行会一直被锁定,其他处理器无法读写该指令要访问的内存区域,因此能保证指令执行的原子性。这个操作过程叫做缓存锁定,通过这种方式来获取锁。这个操作也叫做CAS操作。
  2. 禁止该指令与之前、之后的读写指令重排序。
  3. 把写缓冲区中的所有数据刷新到主内存中。

这里的第2和3条具有跟volatile读写相同的内存效果。

个人理解:

公平锁调用JAVA的lock方法时,通过读volatile变量,间接使用LoadLoad、LoadStore来实现获取主内存数据、业务逻辑处理的功能。

非公平锁是通过利用CPU自己的lock前缀指令,而该lock前缀指令能完全实现volatile相同的内存效果。

concurrent包的实现依据

基于JAVA提供的CAS操作,外加volatile读写,因此JAVA线程之间的通信分为下面4种方式:

  1. A线程写volatile变量,随后B线程读该volatile变量。
  2. A线程写volatile变,随后B线程用CAS更新该volatile变量。
  3. A线程用CAS更新一个volatile变量,随后B线程用CAS更新该volatile变量。
  4. A线程用CAS更新一个volatile变量,随后B线程读该volatile变量。

JAVA的CAS最底层还是调用CPU提供的高效机器级别原子指令,这些原子级别的指令以原子方式对内存执行读-改-写操作,这是多处理器中实现同步的关键,再加上volatile内存特性,这就形成了concurrent包的基础,concurrent包有一个通用化的实现模式:

首先,声明共享变量为volatile;

其次,使用CAS的原子条件更新来实现线程之间的同步;

同时,配合volatile读写和CAS来实现线程之间的通信。

高并发线程/锁/内存处理模型 文章目录锁与线程一、进程/线程的基本介绍进程线程1 线程的调度与时间片2 优先级3 生命周期进程与线程的区别二、线程的使用2.1 Thread类的介绍2.2 创建线程的方法ThreadRunnableCallableFuture利用线程池总结2.3 为什么Executors被禁止使用2.4 线程的API操作2.5 线程间的通信三、线程池的深入不出3.1 ThreadPoolExecutor构造参数说明提交任务方式阻塞队列钩子方法拒绝策略3.2 线程池的任务调度流程3.3 线程池工厂3.4 线程池生命周期/状 阅读详情

相关推荐

Java锁升级的详细介绍

《Java锁机制详解:从偏向锁到重量级锁》 本文系统介绍了Java中的三种锁机制及其升级过程。偏向锁基于"无竞争"假设,通过标记线程ID减少同步开销,适用于单线程重复访问场景;轻量级锁采用CAS操作避免阻塞,适合线程交替执行的轻度竞争环境;重量级锁依赖操作系统互斥量实现严格同步,能处理高并发竞争但性能较低。JVM会根据竞争强度自动升级锁机制(01→00→10),开发者可通过-XX参数调优。随着JDK版本迭代,偏向锁已被标记废弃,推荐使用基于CAS的并发工具。合理选择锁机制对系统性能至关重

weixin_50055999的博客 1322

JAVA开发系统功能占用内存释放测试

查看java程序的资源消耗方法。 查看java程序运行的峰值内存消耗(含虚拟机)和CPU消耗(ms)的方法: 用jdk自带的工具,jconsole.exe; 令行输入jconsole.exe; 就会出现一个window; 根据进程号选择要监控的虚拟机; 里面有内存、线程、包括各种对象定义占有的内存,都可以看到。@TOC 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑...

qq_36869689的博客 470

无锁、偏向锁、轻量级锁、重量级锁

超千万千万

会写Bug的攻城狮 2654

JAVA引用 从零开始的内存释放学习

JAVA引用 从零开始的内存释放学习 当计算机内存被过多无用代码占用时,我们可以通过释放内存这种形式来节省java 程序运行时所占用的内存。但是,这样就存在一个弊端。因为并不是电脑内存越空旷我们的程序就跑的越快。用简单的方法想,就是你实例化类以后。将该类内存释放,然后内存就空了一块。但是你如果还需要继续使用该类的方法就又要重新实例化该类,所以就需要我们要自己判断需不需要释放掉某个类的内存。

菜鸡程序员 1611

实战:如何通过修改VTS和HTS调整GC4653 sensor帧率(附完整计算步骤)

本文以GC4653图像传感器为例,详细解析了通过修改VTS和HTS寄存器来精确调整输出帧率的完整流程。文章深入剖析了帧率计算公式FPS = PCLK / (VTS × HTS)的核心原理,并提供了从获取寄存器参数、计算目标VTS值到系统验证的实战步骤,帮助工程师掌握独立优化Sensor性能、提升低照度画质的关键技能。

gin88的博客 338

使用SAM进行遥感图像语义分割

SAM(Segment Anything Model)的成功表明了以数据为中心的机器学习的重要性。然而,由于遥感(RS)图像注释的困难和高成本,大量有价值的RS数据仍然没有被标记,特别是在像素级。在这项研究中,我们利用SAM和现有的RS物体检测数据集,开发了一个高效的管道来生成大规模的RS分割数据集,称为SAMRS。SAMRS在规模上超过了现有的高分辨率RS分割数据集几个数量级,并提供了物体类别、位置和实例信息,可用于语义分割、实例分割和物体检测,无论是单独还是组合。

lalula的博客 7451

java 内存锁_Java 高并发的几种锁优化方案

Java 语言自身实现的一些并发容器和工具,你了解的越多,越觉得设计的精妙。本文主要讲并行优化的几种方式,其结构如下:锁优化减少锁的持有时间例如避免给整个方法加锁。public synchronized void syncMethod(){othercode1();mutextMethod();othercode2();}改进后:public void syncMethod2(){othercod...

weixin_29340419的博客 529

AD7768与STM32F439的硬件设计避坑指南:如何优化高精度ADC系统的电源与PCB布局

本文详细解析了AD7768与STM32F439在高精度ADC系统硬件设计中的关键问题与优化方案。从电源系统设计、PCB布局到基准电压选型,提供了实用的避坑指南和实测数据,帮助工程师提升系统性能至110dB动态范围。特别强调了SPI信号布线和电源滤波对ADC精度的重要影响。

sugar的博客 735

单例模式 java优缺点_单例模式的5种实现方法及优缺点

文章为本人原创,创作不易,如果对您有帮助,点赞收藏加关注。单例模式的5种实现方法及优缺点单例模式是GoF23种设计模式中创建型模式的一种,也是所有设计模式中最简单的一种。但是最简单的设计模式,也有很多小细节可以讲。单例模式是用来保证系统中某个资源或对象全局唯一的一种模式,比如系统的线程池、日志收集器等。它保证了资源在系统中只有一份,一方面节省资源,另一方面可以避免并发时的内存安全问题。废话不多说,...

weixin_30109877的博客 231

java结合Ai

Spring AI 是 AI 工程的应用框架。其目标是将Spring生态系统的设计原则(如可移植性和模块化设计)应用于AI领域,并促进使用POJO作为应用程序的构建块到AI领域。特征跨 AI 提供商的可移植 API 支持,适用于聊天、文本到图像和嵌入模型。支持同步 API 和流 API 选项。还支持下拉以访问特定于模型的功能。聊天模型亚马逊基岩人类学Cohere的命令AI21 Labs的侏罗纪-2Meta 的 LLama亚马逊的泰坦人类学克劳德Azure 开放式 AI。

qq_67832732的博客 2848

D触发器版图设计的艺术:最小化面积与最大化性能的平衡之道

本文探讨了D触发器版图设计中如何平衡最小化面积与最大化性能的核心挑战。通过分析晶体管布局、互联优化、时钟分布等关键策略,结合先进制程下的功耗与信号完整性考量,为数字IC工程师提供了从基础优化到制造验证的实用解决方案,助力实现高性能、低面积的芯片设计。

aa123的博客 909

单例模式

单例模式 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。 单例类只能有一个实例 单例类必须自己创建自己的唯一实例 单例类必须给所有其他...

ddd的博客 234

本地AI助手部署指南:DeepSeek Harness与Ollama集成实践

AI Agent作为当前人工智能领域的热门技术,通过模拟人类决策过程,能够自主规划、调用工具并执行复杂任务。其核心原理在于将大语言模型的推理能力与外部工具API相结合,形成可闭环的工作流。这种技术架构的价值在于显著提升了AI系统的实用性和自动化水平,使其从单纯的对话工具转变为能够解决实际问题的智能助手。在应用场景上,AI Agent广泛应用于代码生成、数据分析、自动化办公等领域。本文聚焦于如何通过DeepSeek Harness平台与Ollama本地模型的集成,实现隐私安全、离线可用的AI助手部署方案,特别

dengjuanshou7445的博客 474

MiniCPM-o-4.5-nvidia-FlagOS代码解释能力展示:理解复杂Java八股文示例

本文介绍了如何在星图GPU平台上自动化部署MiniCPM-o-4.5-nvidia-FlagOS镜像,并展示了其强大的代码理解与分析能力。该镜像能够深入解读复杂的Java代码,例如剖析单例模式中的双重检查锁定机制,为开发者提供代码设计思路、潜在风险及优化建议,有效辅助代码评审与学习。

weixin_34535286的博客 77

Unity与iOS原生交互实战指南

C#(DllImport) → C 接口(extern "C") → Objective‑C / SwiftObjective‑C → UnitySendMessage → C#(GameObject + public 方法)在写.mm文件;在里面写;C# 用声明;调用它,参数就是 string / 数值等;在.mm里做你想做的 iOS 原生操作。在 Unity 里准备一个常驻 GameObject,比如;上面挂一个脚本,写;在 iOS 插件中用;

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 1357

操作系统|知识梳理|复习(下)

操作系统复习

知识库搭建ing 1784

volatile双重锁实现单例

双重锁实现单例时遭到质疑,既是:双重锁也无法保证单例模式! 原因是:指令会重排序,普通的变量仅仅会保证该方法在执行时,所有依赖的赋值结果是正确的,但不会保证执行顺序! 为什么会重排序:指令重排序是指cpu采用了允许将多条指令不按照程序的顺序分开发送各相应电路单元处理,cpu不会任意排序(深入java虚拟机第12章),但需要重排序提高性能。 怎么解决,标题也写明白了。 使用volatile关...

weixin_33759269的博客 121

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Java中的常见的锁及其内存语义

为什么会有锁? 为什么Java会有锁,这要从Java的内存模型讲起: 大家都知道Java是个多线程语言,这句话的意思是一个Java进程可以创建多个线程来执行指令。对于可并发的编程语言,要怎么做到线程之间是如何通信的,以及线程间是如何同步的? 在命令式编程中,通信机制一般有两种,共享内存和消息传递 共享内存是一种隐式通信,通过访问一个公共的内存区域,来达到线程间数据交互的作用。 消息传递是一种显...

qq_40233503的博客 837

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

深入理解Java锁升级(图解+史上最全):无锁 → 偏向锁 → 轻量级锁 → 重量级锁

锁状态bits1bit是否是偏向锁2bit锁标志位无锁状态对象的hashCode001偏向锁线程ID101轻量级锁指向栈中锁记录的指针000重量级锁指向互斥量的指针010尼恩提示,讲完 如减少锁粒度、锁粗化、关闭偏向锁(-XX:-UseBiasedLocking)等优化手段 , 可以得到 120分了。如减少锁粒度、锁粗化、关闭偏向锁(-XX:-UseBiasedLocking)等‌。JVM锁的膨胀、锁的内存结构变化相关的面试题,是非常常见的面试题。也是核心面试题。

架构师尼恩 3584

java 多线程 内存_Java多线程并发编程9之Java内存模型5(锁的内存语义)

众所周知,锁可以让临界区互斥执行。这里将介绍锁的另一个同样重要,但常常被忽视的功能:锁的内存语义。一、锁的释放-获取建立的happens-before关系锁是Java并发编程中最重要的同步机制。锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息。class MonitorExample { int a = 0;public synchronized void writer...

weixin_42632156的博客 119

Java锁常见面试题

在Java中的锁主要是用于保障线程在多并发的情况下数据的一致性。就是实现并发的原子性。不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁。出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续。如果没有外部干预,线程会一直阻塞无法往下执行,这些一直处于相互等待资源的线程就称为死锁线程。

长江七号的博客 2858

【Java】synchronized关键字详解:从字节码到对象头与锁升级

synchronized底层原理详解 synchronized实现同步的核心机制是通过对象监视器(Monitor)实现的,主要包含以下关键点: 字节码层面 同步代码块编译后会生成monitorenter和monitorexit指令 同步方法通过ACC_SYNCHRONIZED标志实现 对象头与Monitor 每个对象关联一个Monitor对象 对象头中的Mark Word存储锁状态信息 Monitor包含Owner(持有线程)、EntryList(阻塞队列)和WaitSet(等待队列) 锁升级优化 无锁 →

先做到 再看见 4575

《Java并发编程的艺术》第三章读书笔记——3..5 锁的内存语义

3.5.1 锁的释放–获取建立的happens-before关系 锁是java并发编程中最重要的同步机制。锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息。 3.5.2 锁的释放后和获取的内存语义 当线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中。 当线程获取锁时,JMM会把该线程对应的本地内存置为无效。 总结:锁释放与volatile写有相同的语...

你不在我都在的博客 163

JAVA 锁—— synchronized

偏向锁适用于只有一个线程加锁且没有竞争的情况。偏向锁在JDK 6到15中默认开启,但从JDK 15开始默认关闭,JDK 18中彻底移除。偏向锁不会释放,解锁后markWord保持不变。

肢解生活,直达本质;凡所有相,皆是虚妄。 816

读书笔记《JAVA并发编程的艺术》 第三章 Java内存模型 3.5 锁的内存语义

3.5 锁的内存语义 3.5.1 锁的释放–获取建立的happens-before关系 锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息。 3.5.2 锁的释放后和获取的内存语义 当线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中。 当线程获取锁时,JMM会把该线程对应的本地内存置为无效。 总结:锁释放与volatile写有相同的语义...

maohoo的博客 250

java并发编程:管程、内存模型、无锁并发、线程池、AQS原理与锁、线程安全集合类、并发设计模式

java并发编程:管程、内存模型、无锁并发、线程池、AQS原理与锁、线程安全集合类、并发设计模式

Henrik-Yao的博客 1571
上一篇: JAVA内存模式-4-volatile
下一篇: JAVA内存模式-6-final
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值