Java多线程系列——内存模型JMM
目录
核心思想
关键概念
1. 可见性
2. 原子性
3. 有序性
工作原理
并发工具类
对并发编程的影响
同步策略
JMM的实践意义
结语
Java内存模型(Java Memory Model, JMM)是Java并发编程中的核心概念,其定义了Java虚拟机(JVM)在多线程环境中如何以及何时可以看到其他线程写入的变量值,以及如何同步访问共享变量。JMM解决了可见性、原子性、有序性这些在多线程编程中常见的问题。接下来,我们将详细探讨Java内存模型的关键组成部分、工作原理以及它如何影响Java并发编程。
核心思想
JMM围绕内存可见性、原子性和有序性的概念展开,通过定义一系列规则(happens-before规则)来保证并发环境下的线程安全性。JMM确保在多线程执行时,对共享变量的写入能够及时、安全地被其他线程感知。
关键概念
1. 可见性
内存可见性问题发生在多个线程访问同一个变量时,一个线程修改了这个变量的值,但这个新值对其他线程来说不可见。JMM通过volatile关键字提供了一种轻量级的同步机制,保证了对volatile变量的写操作对其他线程立即可见。此外,synchronized和Lock等同步机制也可以解决可见性问题,它们保证只有持有同一个锁的线程才能访问被保护的资源。
2. 原子性
在并发编程中,原子性指的是一个或一系列操作在CPU执行的过程中不被中断的特性。JMM通过synchronized和Lock等机制提供了原子性保证。当一个线程进入一个synchronized块时,它会获取一个锁,直到线程退出synchronized块时才释放锁。这期间,其他线程无法进入这个或任何其他由同一个锁保护的synchronized块。例如,i++
操作不是原子性的,它包含读取i
的值、增加1、写回新值三个步骤,任何步骤都可能被其他线程中断。
3. 有序性
有序性指的是程序执行的顺序按照代码的先后顺序执行。在JMM中,由于编译器优化和处理器优化(即指令重排),程序执行可能会与代码顺序不一致。volatile关键字在这里扮演了重要角色,它可以防止指令重排,保证写操作之前的操作不会被编译器优化到写操作之后。
工作原理
Java内存模型通过happens-before
原则来保证以上三个特性,这个原则定义了内存写入和读取的顺序,确保在没有其他同步手段的情况下,线程之间的操作顺序是可预测的。
- 锁定(Synchronization):当一个线程进入一个同步块时,它会看到由同一个锁保护之前所有的修改效果。
- volatile变量规则:对一个volatile变量的写,对后续对这个volatile变量的读可见。
- 线程启动规则:Thread对象的start()方法之前的写操作,对这个线程可见。
- 线程终止规则:线程中的所有操作都对检测这个线程已经终止的所有线程可见。
- 终结器规则:对象的构造函数执行结束之前对一个对象的写操作,对调用这个对象的finalize方法可见。
并发工具类
Java提供了丰富的并发工具类,如在java.util.concurrent
包下的类,包括线程池(Executors)、并发集合(如ConcurrentHashMap)、同步器(如Semaphore、CountDownLatch、CyclicBarrier)等。这些工具类的设计充分利用了JMM的特性,为开发高效、线程安全的并发应用提供了强有力的支持。
对并发编程的影响
Java内存模型对于设计线程安全的并发程序至关重要。开发者需要正确地使用同步机制(例如synchronized
关键字、volatile
变量、Lock
接口等)来保证操作的原子性、可见性和有序性,避免并发编程中的常见问题,如死锁、数据竞争等。
同步策略
- 封装共享变量:尽量将共享变量私有化,通过内部机制控制对它们的访问。
- 最小锁定范围:尽量缩小锁的范围,只在需要同步的代码区域使用锁。
- 使用高级并发API:Java提供了
java.util.concurrent
包,其中包含了设计用于处理并发的高级API,如ExecutorService
、ConcurrentHashMap
等,这些API利用了Java内存模型的特性,为开发高效并发应用提供了便利。
JMM的实践意义
深入理解JMM对于开发高性能、线程安全的Java并发程序至关重要。它不仅是理论知识,更重要的是,它为开发者提供了一套规则和工具,帮助我们在实际开发中识别和避免并发编程的陷阱。掌握JMM,意味着能够更好地利用Java并发编程的强大能力,编写出既安全又高效的多线程程序。
结语
理解Java内存模型是成为一名优秀Java程序员的关键。它不仅帮助你理解如何在多线程环境下安全地操作共享变量,还能使你能够编写出既高效又线程安全的并发程序。随着Java虚拟机和Java语言本身的不断进化,Java内存模型也会继续发展,为Java并发编程提供更强大的支持。
相关文章:
Java多线程系列——内存模型JMM
目录 核心思想 关键概念 1. 可见性 2. 原子性 3. 有序性 工作原理 并发工具类 对并发编程的影响 同步策略 JMM的实践意义 结语 Java内存模型(Java Memory Model, JMM)是Java并发编程中的核心概念,其定义了Java虚拟机(JV…...

深入理解 Vue3 中的 setup 函数
💗💗💗欢迎来到我的博客,你将找到有关如何使用技术解决问题的文章,也会找到某个技术的学习路线。无论你是何种职业,我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章,也欢…...

【QT+QGIS跨平台编译】之三十六:【RasterLite2+Qt跨平台编译】(一套代码、一套框架,跨平台编译)
文章目录 一、RasterLite2介绍二、文件下载三、文件分析四、pro文件五、编译实践一、RasterLite2介绍 RasterLite2是一个开源的轻量级栅格数据库,可以用于存储和管理各种类型的栅格数据,包括卫星遥感图像、数字高程模型等。 与传统的GIS数据存储方式不同,RasterLite2采用基…...
java面试题:分布式和微服务的区别
1 分布式和微服务概念不同 微服务架构是架构设计方式,是设计层面的东西,一般考虑如何将系统从逻辑上进行拆分,也就是垂直拆分。 分布式系统是部署层面的东西,即强调物理层面的组成,即系统的各子系统部署在不同计算机…...
GO语言的变量与常量
1.变量 go是一个静态语言 变量必须先定义后使用变量必须要有类型 定义变量的方式: var 名称 类型 var 名称 值 名称 :值 例如: var num int 这样就存了一个num类型为int的变量 var num 1 上面使用简化的定义通过num自动判断后面的类型为int并…...

java面试多线程篇
文章说明 在文章中对所有的面试题都进行了难易程度和出现频率的等级说明 星数越多代表权重越大,最多五颗星(☆☆☆☆☆) 最少一颗星(☆) 1.线程的基础知识 1.1 线程和进程的区别? 难易程度:☆☆…...

Anaconda + VS Code 的安装与使用
目录 一. Anaconda 是什么二. Anaconda 的安装1. 下载安装包2. 安装3. 检查 三. Anaconda 的使用1. 创建虚拟环境2. 激活虚拟环境3. 包管理4. 列举虚拟环境5. 退出虚拟环境6. 删除虚拟环境 四. VS Code 开发1. 安装插件2. 打开工作区3. 选择解释器 五. VS Code 个性化设置1. 切…...
Python爬虫html网址实战笔记
仅供学习参考 一、获取文本和链接 import requests from lxml import htmlbase_url "https://abcdef自己的网址要改" response requests.get(base_url) response.encoding utf-8 # 指定正确的编码方式tree html.fromstring(response.content, parserhtml.HTML…...

C++ 调用js 脚本
需求: 使用Qt/C 调用js 脚本。Qt 调用lua 脚本性能应该是最快的,但是需要引入第三方库,虽然也不是特别麻烦,但是调用js脚本,确实内置的功能(C 调用lua 脚本-CSDN博客) 步骤: 1&…...

Vscode python pyside6 制作视频播放器
一、界面如下 包含控件 qcombox、qtablewidget、qpushbotton、qverticalslider 二、运行代码 media_player.py import sysfrom PySide6 import QtWidgets from PySide6.QtWidgets import * from PySide6.QtMultimedia import * from PySide6.QtMultimediaWidgets import QVi…...

纯前端低代码平台demo,vue框架,nodejs,简单的pm2纯前端部署实践
文章目录 目录结构说明本地运行项目启动后的页面demo前端部署打包pm2nginx 后话 前段时间开发了一个纯前端的低代码平台demo,vue框架,nodejs,pm2纯前端部署实践。为此记录一下开发过程以及各方面遇到的问题,并作说明。 表单用了若…...

致创新者:聚焦目标,而非问题
传统的企业创新管理方式常常导致组织内部策略不协调、流程低效、创新失败率高等问题。而创新运营作为企业管理创新的新模式,通过整合文化、实践、人员和工具,提高组织创新能力。已经采用创新运营的公司报告了一系列积极的结果,如市场推出速度…...
javaSE和javaEE区别
javaSE Java SE(Java Platform,Standard Edition) Java SE 以前称为 J2SE。 它允许开发和部署在桌面、服务器、嵌入式环境和实时环境中使用的 Java 应用程序。 Java SE 包含了支持 Java Web服务开发的类,并为 Java Platform&#…...

安装VMware+安装Linux
以上就是VMware在安装时的每一步操作,基本上就是点击 "下一步" 一直进行安装 安装Linux VMware虚拟机安装完毕之后,我们就可以打开VMware,并在上面来安装Linux操作系统。具体步骤如下: 1). 选择创建新的虚拟机 2). 选…...

session和cookie理解
目录 1、理解无状态 2、Session和Cookie理论 3、使用session存储数据 前言,理解session与cookie对于我们做web测试、接口测试、性能测试都是非常有帮助的。 cookie是一些数据信息,存储在浏览器端。 session是存储于服务器端的特殊对象,服务器…...

Springboot医院信息管理系统源码 带电子病历和LIS Saas应用+前后端分离+B/S架构
目录 系统特点 技术架构 系统功能 1、 标准数据维护 2、 收费(门诊/住院)系统 3、 药剂管理系统 4、 医生工作站系统 5、 护士工作站系统 6、电子病历系统 系统优点 云HIS系统简介 云HIS系统功能模块 门急诊挂号管理 门诊收费管理 门诊医…...

LeetCode.589. N 叉树的前序遍历
题目 589. N 叉树的前序遍历 分析 我们之前有做过LeetCode的 144. 二叉树的前序遍历,其实对于 N 插树来说和二叉树的思路是一模一样的。 二叉树的前序遍历是【根 左 右】 N叉树的前序遍历顺序是【根 孩子】,你可以把二叉树的【根 左 右】想象成【根 孩…...

C++ Webserver从零开始:配置环境(九)——下载github的项目进行测试
前言 大家好,我又来更新Webserver的博客了。上一次更新这个专栏时2024.2.5号,离现在已经13天了。非常抱歉,中间隔了那么久。一方面是基础知识学完之后,就要开始自己写代码了。看基础知识和写代码是两回事,理论和实践的…...
2024前端面试准备之TypeScript篇(一)
全文链接 1. 什么是TypeScript TypeScript是一种开源的编程语言,是JavaScript的一个超集。它添加了静态类型、类、接口和模块等特性,使得开发者能够更好地组织和维护大型应用程序。TypeScript代码可以被编译成JavaScript,从而可以在任何支持JavaScript的环境中运行。 2. …...
kali无线渗透之蓝牙攻击与原理
原理 蓝牙网络中的“个人身份码”攻击传统的蓝牙设备,主要是指“蓝牙规范2.1版”以前的各版蓝牙设备,以及使用“安全简化配对”(Secure SimplePairing,SSP)协议的蓝牙设备。 这些传统的蓝牙设备仅仅依赖于“个人身份码”( Personalldentifi…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
二维FDTD算法仿真
二维FDTD算法仿真,并带完全匹配层,输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...