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

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的特性 可见性&#xff1a;对一个volatile变量的读&#xff0c;总能够看到任意一个线程对这个volatile变量的写入。 原子性&#xff1a;对任意单个volatile变量的读/写具有原子性&#xff0c;但类似于volatile这种复合操作不具有原子性。 接下来我们用程序验证。…...

Debezium+Kafka:Oracle 11g 数据实时同步至 DolphinDB 解决方案

随着越来越多用户使用 DolphinDB&#xff0c;各式各样的应用场景对 DolphinDB 的数据接入提出了不同的要求。部分用户需要将 Oracle 11g 的数据实时同步到 DolphinDB 中来&#xff0c;以满足在 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 每日深度学习前沿科技推送&顶会论文分享&#xff0c;与你一起了解前沿深度学习信息&#xff01; 引言&#xff1a;差分隐私在大模型微调中的重要性和挑战 在当今的深度学习领域&#xff0c;大型预训练模型的微调已成为提高各种任务性能的关键技术。然而&am…...

网络空间安全数学基础·整除与同余

主要内容&#xff1a; 整除的基本概念&#xff08;掌握&#xff09; 素数&#xff08;掌握&#xff09; 同余的概念&#xff08;掌握&#xff09; 1.1整除 定义&#xff1a;设a&#xff0c;b是任意两个整数&#xff0c;其中b≠0&#xff0c;如果存在一个整数q&#xff0c;使 …...

同旺科技 FLUKE ADPT 隔离版发布 ---- 说明书

所需设备&#xff1a; 1、FLUKE ADPT 隔离版 内附链接&#xff1b; 应用于&#xff1a;福禄克Fluke 12E / 15BMax / 17B Max / 101 / 106 / 107 应用于&#xff1a;福禄克Fluke 15B / 17B / 18B...

云计算-角色、特性和模型 (Roles, Characteristics, and Models)

角色、特性和模型 (Roles, Characteristics, and Models) 角色和边界 (Roles and Boundaries) 为了识别云计算模型&#xff0c;我们首先需要了解各种参与者的角色和边界。由于云系统通常遵循面向服务的模型&#xff0c;我们需要了解服务提供者和服务订阅者之间的边界。我们将遵…...

介绍一下Hugging Face,这个公司的背景是什么

Hugging Face是一家成立于2016年的人工智能公司&#xff0c;专注于为AI研究人员和开发者提供开源模型库和工具。以下是关于Hugging Face公司的详细背景介绍&#xff1a; 公司历史与创始人&#xff1a; Hugging Face由Clment Delangue、Julien Chaumond和Thomas Wolf三位法国籍…...

【C++高阶(一)】继承

目录 一、继承的概念 1.继承的基本概念 2.继承的定义和语法 3.继承基类成员访问方式的变化 ​编辑 4.总结 二、基类和派生类对象赋值转换 三、继承中的作用域 四、派生类的默认成员函数 1.派生类中的默认构造函数 2.派生类中的拷贝构造函数 3.派生类中的移动构造函数…...

AI原生嵌入式矢量模型数据库ChromaDB-部署与使用指南

在人工智能大模型领域&#xff0c; 离不开NLP技术&#xff0c;在NLP中词向量是一种基本元素&#xff0c;如何存储这些元素呢&#xff1f; 可以使用向量数据库ChromeDB Chroma Chroma 是 AI 原生开源矢量数据库。Chroma 通过为 LLM 提供知识、事实和技能&#xff0c;使构建 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):镜像使用

当运行容器时&#xff0c;使用的镜像如果在本地中不存在&#xff0c;docker 就会自动从 docker 镜像仓库中下载&#xff0c;默认是从 Docker Hub 公共镜像源下载。 一、列出镜像列表 可以使用 docker images 来列出本地主机上的镜像。 各个选项说明&#xff1a; REPOSITORY&am…...

【Git】版本控制工具——Git介绍及使用

目录 版本控制版本控制系统的主要目标分类小结 分布式版本控制系统——GitGit特点Git与SVN的区别Git的工作机制 Git安装Git 团队协作机制团队内协作跨团队协作远程仓库远程仓库的作用有以下几个方面远程仓库操作流程/团队协作流程 Git分支什么是分支分支的好处 Git的常用命令Gi…...

面试八股之JVM篇3.6——垃圾回收——强引用、弱引用、虚引用、软引用

&#x1f308;hello&#xff0c;你好鸭&#xff0c;我是Ethan&#xff0c;一名不断学习的码农&#xff0c;很高兴你能来阅读。 ✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。 &#x1f3c3;人生之义&#xff0c;在于追求&#xff0c;不在成败&#xff0c;勤通…...

博客摘录「 Sql Server 收缩日志文件原理及always on 下的实践」2024年5月22日

四、Always on 环境下实践   先对数据库进行完整备份&#xff1a; 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操作

编写程序&#xff0c;对StringBuffer对象进行追加&#xff0c;插入和修改缓冲区长度等操作&#xff1b; class StringDemo{public static void main(String[] args){boolean btrue;int i321;long l123456;String s1new String("Hello,world!");StringBuffer s2new S…...

默认路由实现两个网段互通实验

默认路由实现两个网段互通实验 **默认路由&#xff1a;**是一种特殊的静态路由&#xff0c;当路由表中与数据包目的地址没有匹配的表项时&#xff0c;数据包将根据默认路由条目进行转发。默认路由在某些时候是非常有效的&#xff0c;例如在末梢网络中&#xff0c;默认路由可以…...

ComfyUI完全入门:图生图局部重绘

大家好&#xff0c;我是每天分享AI应用的萤火君&#xff01; 这篇文章的主题和美女有关&#xff0c;不过并不是教大家生产美女视频&#xff0c;而是讲解 ComfyUI 的图生图局部重绘&#xff0c;其中将会以美女图片为例&#xff0c;来展示局部重绘的强大威力。 先看看效果&…...

基于UDP的网络多人聊天室

UDP服务器 #include <myheader.h>//宏定义打印错误信息 #define PRINT_ERR(msg) \do \{ \printf("%S,%D,%S\n",__FI…...

Godot PCK解包原理与专业逆向实践指南

1. 这不是“解压软件”&#xff0c;而是Godot游戏逆向工程的第一把手术刀你刚下载了一款用Godot引擎开发的独立游戏&#xff0c;想研究它的UI动效逻辑&#xff0c;或者复刻一段粒子特效&#xff0c;又或者只是单纯好奇——那个让你反复通关三次的像素风过场动画&#xff0c;图层…...

无机布防火卷帘门价格怎么算?按尺寸定制,按需报价

无机布防火卷帘门作为建筑防火分区的核心设备&#xff0c;价格一直是工程采购的关注重点。很多用户在询价时&#xff0c;会发现不同厂家的报价差异较大&#xff0c;这是因为无机布防火卷帘门的价格并非按统一单价计算&#xff0c;而是完全根据项目的实际需求定制化核算。 &…...

Unity安卓构建72小时实战指南:从零到真机运行

1. 这不是“又一本Unity教程”&#xff0c;而是我带三个新人从零上线第一款安卓游戏的真实路径你点开这个标题&#xff0c;大概率正站在两个路口之间&#xff1a;一边是满屏“30天速成Unity”“零基础做爆款”的短视频封面&#xff0c;一边是你刚下载完Unity Hub、卡在Android …...

DMA-330地址空间限制与扩展方案解析

1. DMA-330地址空间限制解析DMA-330作为Arm CoreLink系列中的直接内存访问控制器&#xff0c;其物理寻址能力直接由AxADDR信号宽度决定。这个32位地址总线宽度意味着它原生仅支持4GB&#xff08;2^32字节&#xff09;的物理地址空间访问。在实际嵌入式系统设计中&#xff0c;这…...

终极艾尔登法环帧率解锁指南:轻松突破60FPS限制

终极艾尔登法环帧率解锁指南&#xff1a;轻松突破60FPS限制 【免费下载链接】EldenRingFpsUnlockAndMore A small utility to remove frame rate limit, change FOV, add widescreen support and more for Elden Ring 项目地址: https://gitcode.com/gh_mirrors/el/EldenRing…...

独立站内容分层:一层给 SEO,一层给 GEO

你的内容在喂两个完全不同的"阅读者" 你的博客文章&#xff0c;从来都不只有一个读者。 传统认知里&#xff0c;独立站内容的读者只有两类&#xff1a;真人访客和搜索引擎爬虫。SEO 优化的一切工作&#xff0c;本质上都是在讨好后者&#xff0c;顺带服务前者。 但…...

告别硬编码!在UE5.1里用蓝图动态配置MySQL连接参数(控件蓝图实战)

动态配置MySQL连接&#xff1a;UE5.1控件蓝图的工程化实践在游戏开发中&#xff0c;数据库连接往往是项目架构中不可或缺的一环。传统硬编码方式虽然简单直接&#xff0c;却带来了维护困难、安全性差、灵活性低等一系列问题。本文将深入探讨如何在UE5.1中构建一个完全动态化的M…...

PvZ Toolkit终极指南:三步掌握植物大战僵尸最强修改器

PvZ Toolkit终极指南&#xff1a;三步掌握植物大战僵尸最强修改器 【免费下载链接】pvztoolkit 植物大战僵尸 PC 版综合修改器 项目地址: https://gitcode.com/gh_mirrors/pv/pvztoolkit PvZ Toolkit是一款专为植物大战僵尸PC版设计的综合修改器工具&#xff0c;能够让你…...

2026这6款神级降AIGC平台大公开,一键让AIGC率直逼绝对安全线!

步入 2026 年&#xff0c;学术圈的风向早已不是从前的模样。曾经大家还在为查重率发愁&#xff0c;如今却陷入了更棘手的困境——如何在不破坏论文专业性的前提下&#xff0c;彻底消除 AI 痕迹&#xff1f;随着 AIGC 检测技术不断进化&#xff0c;高校对论文的审核标准也愈发严…...

基于MAX78000的边缘AI语音识别:从模型训练到嵌入式部署实战

1. 项目概述与核心思路最近在捣鼓一个挺有意思的小项目&#xff0c;我把它叫做“声控转向控制器”。简单来说&#xff0c;这玩意儿能听懂你说的几个特定单词&#xff0c;比如“左转”、“右转”、“前进”、“后退”&#xff0c;然后控制对应的LED灯亮起。你可能会想&#xff0…...