Volatile的内存语义
1、volatile的特性
可见性:对一个volatile变量的读,总能够看到任意一个线程对这个volatile变量的写入。
原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性。
接下来我们用程序验证。
public class OldVolatileFeaturesExample {volatile long v1 = 0L; // 使用volatile 声明64位的long型变量//long v1 = 0L;public void set(long l){v1 = l; //单个volatile 变量的写}public void getAndIncrement(){v1++; // 多个volatile 变量的读/写}public long get(){return v1; // 单个volatile 变量的读}public static void main(String[] args) {final OldVolatileFeaturesExample volatileFeaturesExamlple = new OldVolatileFeaturesExample();Thread thread0 = new Thread(new Runnable() {public void run() {volatileFeaturesExamlple.set(1L);}});thread0.start();Thread thread1 = new Thread(new Runnable() {public void run() {volatileFeaturesExamlple.getAndIncrement();}});thread1.start();Thread thread2 = new Thread(new Runnable() {public void run() {long l = volatileFeaturesExamlple.get();System.out.println("创建的l值-------"+ l);}});thread2.start();/* for (int i = 0; i < 10; i++) {Thread thread0 = new Thread(new Runnable() {public void run() {volatileFeaturesExamlple.set(1L);}});thread0.start();Thread thread1 = new Thread(new Runnable() {public void run() {volatileFeaturesExamlple.getAndIncrement();}});thread1.start();Thread thread2 = new Thread(new Runnable() {public void run() {long l = volatileFeaturesExamlple.get();System.out.println("创建的l值-------"+ l);}});thread2.start();}*/}}
这里,线程thread0 设置使用volatile修饰的long类型变量 v1 ;线程thread1 进行v1++操作, thread2 获取变量v1的值,并打印结果。那么 v1的值是几呢?
上面这段程序运行结果是:
创建的l值-------2
那么就算不用volatile修饰的v1变量,也执行上述操作,结果会是什么样子呢?没错,还是2。
那么使用volatile修饰的v1变量 当使用for 循环呢?也就是多个volatile变量的读写操作的结果:
创建的l值-------2
创建的l值-------2
创建的l值-------1
创建的l值-------1
创建的l值-------1
创建的l值-------2
创建的l值-------3
创建的l值-------1
创建的l值-------2
创建的l值-------3
假设具有原子性,那么v1循环加10次 1,那么它的结果应该是 10,而不是上面的结果。上面的程序等价于:
public class NewVolatileFeaturesExample {long v1 = 0L;public synchronized void set(long l){ //对单个的普通变量的写用同一个锁同步v1 = l;}public void getAndIncrement(){ //普通方法调用long temp = get(); //调用已同步的读方法temp += 1L; //普通写操作set(temp); //调用已同步的写方法}public synchronized long get(){ // 对单个的普通变量的读用同一个锁同步return v1;}public static void main(String[] args) {final NewVolatileFeaturesExample newVolatileFeaturesExample = new NewVolatileFeaturesExample();/* for (int i = 0; i < 10; i++) {Thread thread0 = new Thread(new Runnable() {public void run() {newVolatileFeaturesExample.set(1L);}});thread0.start();Thread thread1 = new Thread(new Runnable() {public void run() {newVolatileFeaturesExample.getAndIncrement();}});thread1.start();Thread thread2 = new Thread(new Runnable() {public void run() {long l = newVolatileFeaturesExample.get();System.out.println("创建的l值-------"+ l);}});thread2.start();}*/Thread thread0 = new Thread(new Runnable() {public void run() {newVolatileFeaturesExample.set(1L);}});thread0.start();Thread thread1 = new Thread(new Runnable() {public void run() {newVolatileFeaturesExample.getAndIncrement();}});thread1.start();Thread thread2 = new Thread(new Runnable() {public void run() {long l = newVolatileFeaturesExample.get();System.out.println("创建的l值-------"+ l);}});thread2.start();}
}
这个也就是相当于对v1变量的读和写进行了synchronized 同步锁操作。
而锁的语义决定了临界区代码的执行具有原子性。锁的happens-before 规则保证了释放锁和获取锁的两个线程之间的内存可见性。那么volatile 写和读建立的happens-before 关系是又是什么样子呢?欲知后事如何,请看下回分解。
更多创作在我的公众号里哦。

相关文章:
Volatile的内存语义
1、volatile的特性 可见性:对一个volatile变量的读,总能够看到任意一个线程对这个volatile变量的写入。 原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile这种复合操作不具有原子性。 接下来我们用程序验证。…...
Debezium+Kafka:Oracle 11g 数据实时同步至 DolphinDB 解决方案
随着越来越多用户使用 DolphinDB,各式各样的应用场景对 DolphinDB 的数据接入提出了不同的要求。部分用户需要将 Oracle 11g 的数据实时同步到 DolphinDB 中来,以满足在 DolphinDB 中实时使用数据的需求。本篇教程将介绍使用 Debezium 来实时捕获和发布 …...
前端如何在 WebSocket 的请求头中使用标准 HTTP 头携带 Authorization 信息,添加请求头
WebSocket 的请求头(header)中如何携带 authorization...
Java---图书管理系统(练习版)
1.主函数 import book.Book; import book.BookList; import user.AdminUser; import user.NormalUser; import user.User;import java.util.Scanner;public class Main {public static User Login(){//确认你的身份System.out.println("请输如你的名字");Scanner sc…...
ICML2024 定义新隐私保护升级:DP-BITFIT新型微调技术让AI模型学习更安全
DeepVisionary 每日深度学习前沿科技推送&顶会论文分享,与你一起了解前沿深度学习信息! 引言:差分隐私在大模型微调中的重要性和挑战 在当今的深度学习领域,大型预训练模型的微调已成为提高各种任务性能的关键技术。然而&am…...
网络空间安全数学基础·整除与同余
主要内容: 整除的基本概念(掌握) 素数(掌握) 同余的概念(掌握) 1.1整除 定义:设a,b是任意两个整数,其中b≠0,如果存在一个整数q,使 …...
同旺科技 FLUKE ADPT 隔离版发布 ---- 说明书
所需设备: 1、FLUKE ADPT 隔离版 内附链接; 应用于:福禄克Fluke 12E / 15BMax / 17B Max / 101 / 106 / 107 应用于:福禄克Fluke 15B / 17B / 18B...
云计算-角色、特性和模型 (Roles, Characteristics, and Models)
角色、特性和模型 (Roles, Characteristics, and Models) 角色和边界 (Roles and Boundaries) 为了识别云计算模型,我们首先需要了解各种参与者的角色和边界。由于云系统通常遵循面向服务的模型,我们需要了解服务提供者和服务订阅者之间的边界。我们将遵…...
介绍一下Hugging Face,这个公司的背景是什么
Hugging Face是一家成立于2016年的人工智能公司,专注于为AI研究人员和开发者提供开源模型库和工具。以下是关于Hugging Face公司的详细背景介绍: 公司历史与创始人: Hugging Face由Clment Delangue、Julien Chaumond和Thomas Wolf三位法国籍…...
【C++高阶(一)】继承
目录 一、继承的概念 1.继承的基本概念 2.继承的定义和语法 3.继承基类成员访问方式的变化 编辑 4.总结 二、基类和派生类对象赋值转换 三、继承中的作用域 四、派生类的默认成员函数 1.派生类中的默认构造函数 2.派生类中的拷贝构造函数 3.派生类中的移动构造函数…...
AI原生嵌入式矢量模型数据库ChromaDB-部署与使用指南
在人工智能大模型领域, 离不开NLP技术,在NLP中词向量是一种基本元素,如何存储这些元素呢? 可以使用向量数据库ChromeDB Chroma Chroma 是 AI 原生开源矢量数据库。Chroma 通过为 LLM 提供知识、事实和技能,使构建 L…...
c# 画一个正弦函数
1.概要 c# 画一个正弦函数 2.代码 using System; using System.Drawing; using System.Windows.Forms;public class SineWaveForm : Form {private const int Width 800;private const int Height 600;private const double Amplitude 100.0;private const double Period…...
Docker学习(3):镜像使用
当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。 一、列出镜像列表 可以使用 docker images 来列出本地主机上的镜像。 各个选项说明: REPOSITORY&am…...
【Git】版本控制工具——Git介绍及使用
目录 版本控制版本控制系统的主要目标分类小结 分布式版本控制系统——GitGit特点Git与SVN的区别Git的工作机制 Git安装Git 团队协作机制团队内协作跨团队协作远程仓库远程仓库的作用有以下几个方面远程仓库操作流程/团队协作流程 Git分支什么是分支分支的好处 Git的常用命令Gi…...
面试八股之JVM篇3.6——垃圾回收——强引用、弱引用、虚引用、软引用
🌈hello,你好鸭,我是Ethan,一名不断学习的码农,很高兴你能来阅读。 ✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。 🏃人生之义,在于追求,不在成败,勤通…...
博客摘录「 Sql Server 收缩日志文件原理及always on 下的实践」2024年5月22日
四、Always on 环境下实践 先对数据库进行完整备份: EXEC sp_configure show advanced options, 1; RECONFIGURE; EXEC sp_configure xp_cmdshell, 1; RECONFIGURE; DECLARE DbName NVARCHAR(1000); DECLARE myCursor CURSOR LOCAL STATIC FOR S…...
每日一题(5)——StringBuffer操作
编写程序,对StringBuffer对象进行追加,插入和修改缓冲区长度等操作; class StringDemo{public static void main(String[] args){boolean btrue;int i321;long l123456;String s1new String("Hello,world!");StringBuffer s2new S…...
默认路由实现两个网段互通实验
默认路由实现两个网段互通实验 **默认路由:**是一种特殊的静态路由,当路由表中与数据包目的地址没有匹配的表项时,数据包将根据默认路由条目进行转发。默认路由在某些时候是非常有效的,例如在末梢网络中,默认路由可以…...
ComfyUI完全入门:图生图局部重绘
大家好,我是每天分享AI应用的萤火君! 这篇文章的主题和美女有关,不过并不是教大家生产美女视频,而是讲解 ComfyUI 的图生图局部重绘,其中将会以美女图片为例,来展示局部重绘的强大威力。 先看看效果&…...
基于UDP的网络多人聊天室
UDP服务器 #include <myheader.h>//宏定义打印错误信息 #define PRINT_ERR(msg) \do \{ \printf("%S,%D,%S\n",__FI…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇
根据 QYResearch 发布的市场报告显示,全球市场规模预计在 2031 年达到 9848 万美元,2025 - 2031 年期间年复合增长率(CAGR)为 3.7%。在竞争格局上,市场集中度较高,2024 年全球前十强厂商占据约 74.0% 的市场…...
负载均衡器》》LVS、Nginx、HAproxy 区别
虚拟主机 先4,后7...
leetcode73-矩阵置零
leetcode 73 思路 记录 0 元素的位置:遍历整个矩阵,找出所有值为 0 的元素,并将它们的坐标记录在数组zeroPosition中置零操作:遍历记录的所有 0 元素位置,将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...
