volatile关键字

1.什么是volatile?

1.1.volatile是一种同步机制,比synchronized或Lock更轻量级,因为使用volatile并不会发生线程“上下

      文切换”等开销很大的行为,volatile关键字只是把被修饰的变量修改后刷新到“主内存”中;

1.2.如果一个变量被volatile修饰,那么JVM就知道这个变量可能会被并发修改;

1.3.volatile属于轻量级同步机制,做不到像synchronized那样的原子保护,其仅在有限的场景下使用;

2.volatile使用场景

适用场景

        1.纯赋值

如果一个共享变量自始至终只被各个线程赋值,而没有其它操作(运算或取反等操作),那么就可以使用volatile代替synchronized或者“原子变量”,因为赋值本身是原子性的,而volatile又保证了可见性所以是线程安全的;

import java.util.concurrent.atomic.AtomicInteger;
/*** 演示volatile适用于纯赋值场景用于保证线程安全*/
public class UseVolatile implements Runnable{volatile boolean flag = false;AtomicInteger realA = new AtomicInteger();@Overridepublic void run() {for (int i = 0; i <10000 ; i++) {setFlag();realA.incrementAndGet(); // 累加}}private void setFlag() {flag = true; // 此种写法无线程安全问题,纯赋值// flag = !flag; // 若这样写则有线程安全问题,因为此处的赋值依赖于之前的变量值;  }public static void main(String[] args) throws InterruptedException {UseVolatile r = new UseVolatile();Thread thread1 = new Thread(r);Thread thread2 = new Thread(r);thread1.start();thread2.start();// 主线程等待子线程执行完thread1.join();thread2.join();System.out.println("volatile适用于纯赋值: " + r.flag);System.out.println("执行次数: " + r.realA); // 20000}
}

2.作为刷新之前变量的触发器

伪代码示例

/* 模拟volatile作为“触发器”多线程初始化完成后去执行任务 */
Map configOptions;
cahr[] configText;
volatile boolean initialized = false; // 此字段被volatile修饰,用于判断是否完成初始化// 线程一
configOptions = new HashMap();
configText = readConfigFile(fileName);
processConfigOptions(configText,configOptions)
initialized = true; // initialized被volatile修饰具有禁止指令重排性,当initialized=true;代表上面configOptions、configText等参数或方法已经完成了初始化; // 线程二
while(!initialized){ // 此时的initialized作为触发器(因为initialized被volatile修饰具有可见性所以线程一的修改线程二能看见,只有当线程一完成了初始化,线程二才会去具体执行的业务,不然一直在循环中休眠等待初始化完成...)Thread.sleep(1000);
}// 线程一初始化完成线程二去做其它业务..use config make todo...

不适用场景

        1.不适用于a++

import java.util.concurrent.atomic.AtomicInteger;
/*** 演示volatile不适用于a++场景*/
public class NoVolatile implements Runnable{volatile int a;// 变量realA主要用于与变量a做对比AtomicInteger realA = new AtomicInteger();@Overridepublic void run() {for (int i = 0; i <10000 ; i++) {a++;realA.incrementAndGet(); // 累加}}public static void main(String[] args) throws InterruptedException {NoVolatile r = new NoVolatile();Thread thread1 = new Thread(r);Thread thread2 = new Thread(r);thread1.start();thread2.start();// 主线程等待子线程执行完thread1.join();thread2.join();System.out.println("使用volatile修饰变量a的最终累加值为: " + r.a);System.out.println("最终累加正确值应为: " + r.realA); // 20000}
}

3.volatile的两点作用

3.1.可见性

     读一个volatile修饰的变量前需先使这个变量在线程内部相应的缓存失效(内部缓存:即每个线程独占的缓存),这样就必须去主内存中读取最新值(主内存:即所有线程共享的内存),当写一个volatile变量时会立即刷入到主内存中;

3.2.禁止指令重排序

        

4.volatile与synchronized关系

    volatile可以看做是一个轻量级的synchronized,如果一个共享变量自始至终都是被各个线程赋值,而没有做其它操作(运算或取反等操作),那么就可以使用volatile代替synchronized,因为赋值本身是原子性的,而volatile又保证了可见性所以是线程安全的;

5.volatile总结

5.1.volatile适用于一个共享变量自始至终只被各个线程赋值,而没有其它操作(运算或取反等操作),那

       么就可以使用volatile代替synchronized或者“原子变量”,因为赋值本身是原子性的,而volatile又

        保证了可见性所以是线程安全的;或者也可以使用volatile作为触发器实现轻量数据同步;

5.2.volatile属性的读写操作都是无锁的,它不能替代synchronized因为它没有提供原子性互斥性,

      因为无锁所以不需要花时间在获取锁和释放锁上所以它是轻量级的;

5.3.volatile只能修饰属性,使用volatile修饰的属性不会被编译器“指令重排”;

5.4.volatile提供了可见性,任何一个线程对其修饰的属性进行修改,其它线程会立马可见,volatile属性

       不会被线程缓存,始终从主内存中取;

5.5.volatile提供了happens-before保证;       

5.6.volatile可以使long和double的赋值是原子的(long和double本身赋值并不能保证是原子性的);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/237454.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Bash 脚本学习

文章目录 1、脚本编程基础2. 变量2.1 参数变量的引用2.2 环境变量 3 条件判断语句3.1 if 语句3.1.1 语法3.1.2 案例 3.2 case 语句3.2.1 语法3.2.2 案例 3.3 判断参数说明 4 循环语句4.1 for 循环4.1.1 语法4.1.2 案例 4.2 while循环4.2.1 语法4.2.2 案例4. 3 循环总结 5. 函数…

Prompt-to-Prompt:基于 cross-attention 控制的图像编辑技术

Hertz A, Mokady R, Tenenbaum J, et al. Prompt-to-prompt image editing with cross attention control[J]. arXiv preprint arXiv:2208.01626, 2022. Prompt-to-Prompt 是 Google 提出的一种全新的图像编辑方法&#xff0c;不同于任何传统方法需要用户指定编辑区域&#xff…

微信小程序开发系列-01创建一个最小的小程序项目

本文讲述了通过微信开发者工具&#xff0c;创建一个新的小程序项目&#xff0c;完全从零开始&#xff0c;不依赖开发者工具的模板。目的是为了更好的理解小程序工程项目的构成。 文章目录 创建一个空项目app.json全局配置pagessitemapLocation app.js 创建一个空项目 打开微信…

新型智慧视频监控系统:基于TSINGSEE青犀边缘计算AI视频识别技术的应用

边缘计算AI智能识别技术在视频监控领域的应用有很多。这项技术结合了边缘计算和人工智能技术&#xff0c;通过在摄像头或网关设备上运行AI算法&#xff0c;可以在现场实时处理和分析视频数据&#xff0c;从而实现智能识别和分析。目前来说&#xff0c;边缘计算AI视频智能技术可…

aws-waf-cdn 基于规则组的永黑解决方案

1. 新建waf 规则组 2. 为规则组添加规则 根据需求创建不同的规则 3. waf中附加规则组 &#xff08;此时规则组所有规则都会附加到waf中&#xff0c;但是不会永黑&#xff09; 此刻&#xff0c;可以选择测试下规则是否生效&#xff0c;测试前确认保护资源绑定无误 4. 创建堆…

大数据开发职业规划

大数据开发职业规划 我的学历是双非本&#xff0c;在学校学习的是大数据专业&#xff0c;目前是在企业做大数据全栈的工作&#xff0c;爬虫&#xff0c;数仓&#xff0c;风控项目&#xff0c;etl开发都做 .................................................................…

FFmpeg实现rtp推流

以下是一个简单的示例代码&#xff0c;演示了如何使用 UDP 或 TCP 进行音视频传输&#xff1a; 代码未经验证&#xff0c;供参考 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #in…

Mac设置ll永久生效,设置.bash_profile生效

Mac设置ll永久生效&#xff0c;设置.bash_profile生效 前言&#xff1a;Mac上自带的终端不好用&#xff0c;一般我推荐ITerm终端&#xff0c;官网下载即可 如果想只生效一次&#xff1a; 直接在终端执行alias llls -l即可 如果想永久生效&#xff1a; vim ~/.bash_profile&…

02 - Kbuild子系统(整理中)

1. Kbuild简介 Kernel build&#xff0c;用来编译 Linux 内核基于 GNU make 设计&#xff0c;对 Makefile 进行扩充 菜单式配置&#xff1a;Kconfig预定义目标和变量&#xff1a;xx_defconfig、menuconfig、obj-y跨平台工具、递归式 Makefile Linux 模块化设计、高度可以裁剪 …

java开发面试:常见业务场景之单点登录SSO(JWT)、权限认证、上传数据的安全性的控制、项目中遇到的问题、日志采集(ELK)、快速定位系统的瓶颈

单点登录&#xff08;SSO&#xff09; 单点登录&#xff0c;Single Sign On&#xff08;简称SSO&#xff09;,只需要登录一次&#xff0c;就可以访问所有信任的应用系统。 如果是单个tomcat服务&#xff0c;session可以共享&#xff0c;如果是多个tomcat&#xff0c;那么服务s…

tcp 的限制 (TCP_WRAPPERS)

#江南的江 #每日鸡汤&#xff1a;青春是打开了就合不上的书&#xff0c;人生是踏上了就回不了头的路&#xff0c;爱情是扔出了就收不回的赌注。 #初心和目标&#xff1a;拿到高级网络工程师 TCP_WRAPPERs Tcp_wrappers 对于七层模型中是位于第四层的安全工具&#xff0c;他…

微信小程序 动态设置状态栏样式

onLoad(options) {//修改状态栏标题wx.setNavigationBarTitle({title: 页面标题, //页面标题success: () > {}, //接口调用成功的回调函数fail: () > {}, //接口调用失败的回调函数complete: () > {} //接口调用结束的回调函数&#xff08;调用成功、失败…

[CVPR 2023:3D Gaussian Splatting:实时的神经场渲染]

文章目录 前言小结 原文地址&#xff1a;https://blog.csdn.net/qq_45752541/article/details/132854115 前言 mesh 和点是最常见的3D场景表示&#xff0c;因为它们是显式的&#xff0c;非常适合于快速的基于GPU/CUDA的栅格化。相比之下&#xff0c;最近的神经辐射场&#xf…

从0开始学Git指令

从0开始学Git指令 因为网上的git文章优劣难评&#xff0c;大部分没有实操展示&#xff0c;所以打算自己从头整理一份完整的git实战教程&#xff0c;希望对大家能够起到帮助&#xff01; 初始化一个Git仓库&#xff0c;使用git init命令。 添加文件到Git仓库&#xff0c;分两步…

Ceph基本环境配置

基本环境准备 准备三台服务器&#xff08;服务器至少需要添加两块磁盘&#xff09;以及一台客户端&#xff0c;最好配置时间同步同时再次配置hosts解析。 node1192.168.134.160node2192.168.134.161node3192.168.134.162node4192.168.134.163客户端 配置免密登录 [rootnode…

智能优化算法应用:基于金鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于金鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于金鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.金鹰算法4.实验参数设定5.算法结果6.参考文献7.MA…

多模态大模型机器人VIMA讲解与资料整理 #持续更新

简单录制了一个视频&#xff0c;欢迎查看&#xff0c;希望对您有帮助&#xff1a; 具身智能开源工作试玩&#xff1a;VIMA_哔哩哔哩_bilibili 参考资料&#xff1a; 多模态prompt通往通用机器人操控——VIMA论文解读 - 知乎 (zhihu.com) 40. VIMA&#xff1a;基于多模态输入…

数据库学习日常案例20231221-oracle libray cache lock分析

1 问题概述&#xff1a; 阻塞的源头为两个ddl操作导致大量的libray cache lock 其中1133为gis sde的create table as语句。 其中697为alter index语句。

第二十一章网络通讯

网络程序设计基础 局域网与互联网 为了实现两台计算机的通信&#xff0c;必须用一个网络线路连接两台计算机。如下图所示 网络协议 1.IP协议 IP是Internet Protocol的简称&#xff0c;是一种网络协议。Internet 网络采用的协议是TCP/IP协议&#xff0c;其全称是Transmission…

2312llvm,05后端下

匹配模式 每个目标都有个叫<Target_Name>DAGToDAGISel的SelectionDAGISel子类.它通过实现子类的Select方法来选指. 如SPARC中的SparcDAGToDAGISel::Select()(见lib/Target/Sparc/SparcISelDAGToDAG.cpp文件).接收要匹配的SDNode参数,返回代表物理指令的SDNode值;否则出…