【JAVA进阶篇教学】第十三篇:Java中volatile关键字讲解

博主打算从0-1讲解下java进阶篇教学,今天教学第十三篇:volatile关键字讲解。

在 Java 中,volatile关键字是一种轻量级的同步机制,用于确保变量的可见性和禁止指令重排序。本文将详细解释volatile关键字的工作原理、可见性保证以及与其他锁的相似之处,并通过代码示例进行说明。

目录

一、volatile关键字作用 

二、volatile关键字原理

三、volatile关键字的可见性

四、volatile关键字与锁的相似之处

五、volatile关键字的禁止指令重排序

六、总结


一、volatile关键字作用 

volatile 关键字用于修饰变量,确保多线程环境下对该变量的读写操作是可见的。具体来说,当一个线程修改了 volatile 变量的值时,其他线程能够立即看到这个修改,从而避免了线程之间的数据不一致性问题。

二、volatile关键字原理

volatile 关键字的可见性是通过在编译器和运行时进行一系列优化来实现的。在编译器层面,volatile 变量的读写操作会插入内存屏障指令,确保了线程在进行读写操作时能够从主内存中读取最新的值或将修改后的值刷新到主内存中。在运行时,JVM 会确保对 volatile 变量的操作是原子的,从而保证了多线程环境下的可见性。

注意:volatile并不能保证数据的原子性!

三、volatile关键字的可见性

volatile关键字可以确保变量的可见性。当一个变量被声明为volatile时,它告诉 Java 虚拟机(JVM),这个变量可能会被多个线程同时访问,并且线程对该变量的修改对于其他线程是可见的。

以下是一个简单的示例代码,演示了volatile关键字的可见性:

public class VolatileVisibilityExample {private volatile boolean flag = false;public void setFlag(boolean value) {flag = value;}public boolean isFlagSet() {return flag;}public static void main(String[] args) {VolatileVisibilityExample example = new VolatileVisibilityExample();// 创建并启动线程Thread thread = new Thread(() -> {while (!example.isFlagSet()) {// 等待 flag 变为 true}System.out.println("Flag 已设置为 true");});thread.start();// 修改 flag 的值example.setFlag(true);}
}

在上述示例中,我们创建了一个名为flag的volatile变量,并在一个线程中不断检查它的值。在主线程中,我们修改了flag的值,并期望子线程能够立即看到这个修改。由于flag是volatile变量,所以线程对flag的修改对于其他线程是可见的,子线程将立即退出循环并输出"Flag 已设置为 true"。

四、volatile关键字与锁的相似之处

  • volatile关键字和锁都可以用于实现线程之间的同步,但它们的实现方式和适用场景有所不同。
  • volatile关键字是一种轻量级的同步机制,它不会引起线程的阻塞和唤醒,因此执行效率较高。但是,volatile关键字只能保证变量的可见性,不能保证原子性。如果需要实现原子性操作,需要使用锁或其他同步机制。
  • 锁是一种更重量级的同步机制,它可以保证原子性、可见性和有序性。锁的实现通常基于操作系统的互斥锁或信号量,因此执行效率较低。但是,锁可以用于实现更复杂的同步逻辑,例如实现临界区、读写锁等。

五、volatile关键字的禁止指令重排序

  • 除了可见性保证之外,volatile关键字还可以禁止指令重排序。指令重排序是一种优化技术,它可以在不改变程序语义的情况下,重新排列指令的执行顺序,以提高执行效率。但是,指令重排序可能会导致多线程程序出现问题,例如竞态条件、数据不一致等。
  • volatile关键字通过添加内存屏障来禁止指令重排序。内存屏障是一种硬件机制,它可以确保在执行当前指令之前,先执行之前的所有内存操作,并且在执行当前指令之后,再执行之后的所有内存操作。这样可以保证指令的执行顺序不会被重排序。

以下是一个简单的示例代码,演示了volatile关键字的禁止指令重排序:

public class VolatileMemoryOrderingExample {private volatile int value = 0;public void setValue(int value) {this.value = value;}public int getValue() {return value;}public static void main(String[] args) {VolatileMemoryOrderingExample example = new VolatileMemoryOrderingExample();// 创建并启动线程Thread thread = new Thread(() -> {int expectedValue = 1;while (example.getValue()!= expectedValue) {// 等待 value 变为 1}System.out.println("Value 已设置为 1");});thread.start();// 修改 value 的值example.setValue(1);}
}

在上述示例中,我们创建了一个名为value的volatile变量,并在一个线程中不断检查它的值。在主线程中,我们修改了value的值,并期望子线程能够立即看到这个修改。由于value是volatile变量,并且使用了内存屏障来禁止指令重排序,所以线程对value的修改对于其他线程是可见的,子线程将立即退出循环并输出"Value 已设置为 1"。

六、总结

volatile关键字是 Java 中的一种轻量级同步机制,它可以确保变量的可见性和禁止指令重排序。volatile关键字适用于多线程环境下的变量共享,例如状态标志、计数器等。与锁相比,volatile关键字的执行效率较高,但不能保证原子性。如果需要实现原子性操作,需要使用锁或其他同步机制。

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Goland GC

Goland GC 引用Go 1.3 mark and sweep 标记法Go 1.5 三色标记法屏障机制插入屏障删除写屏障总结 Go 1.8 混合写屏障(hybrid write barrier)机制总结 引用 https://zhuanlan.zhihu.com/p/675127867 Garbage Collection,缩写为GC,一种内存管理回收的机制…

MyBatis-plus(一):快速入门

目录 一、MyBatis-plus 快速入门 1、原理 2、实体类命名规则 3、常见注解 4、主键 id 策略 5、使用 TableField 的常见场景 6、常用配置 二、核心功能 1、条件构造器 2、自定义 SQL 3、IService 接口 一、MyBatis-plus 快速入门 1、原理 MyBatisPlus 通过扫描实体…

如何使用联合体判断一个机器是大端还是小端

如何使用联合体判断一个机器是大端还是小端 #include<iostream> using namespace std; union Checker//联合体中的数据共享内存 {int val;char ch[2]; }; int main() {Checker checker;checker.val 0x1234;if (checker.ch[0] 0x34)//数组中的数据是由低地址往高地址存放…

CCC数字钥匙各版本关系

CCC钥匙规范版本关系 CCC数字钥匙架构Overview

BGP(border gateway protocol)边界网关协议初识篇

BGP它是一种路径矢量协议&#xff0c;用于决定数据包在互联网中的最佳路径。 1、工作原理&#xff1a; 自治系统&#xff08;AS&#xff09;间路由: BGP主要用于连接不同自治系统之间的路由器&#xff0c;其中每个自治系统&#xff08;AS&#xff09;代表一组具有共同路由的网…

AJ65SBT2B-64DA 三菱CC-Link D/A转换模块

AJ65SBT2B-64DA 是将数字值(16位有符号BIN数据)转换为模拟值(电压或电流)的模块。 AJ65SBT2B-64DA参数说明&#xff1a;4通道&#xff1b;输入分辨率0~12000&#xff0c;-12000~12000&#xff0c;-16000~16000&#xff1b;输出DC-10~10V&#xff0c;DC0~20mA&#xff1b;转换速…

引入Minio

前置条件 官网&#xff1a;https://www.minio.org.cn/download.shtml#/kubernetes 命令 # 查看系统上的网络连接和监听端口信息 netstat -tpnl # 检查系统的指定端口占用情况 sudo netstat -tuln | grep 9000systemctl status firewalld # 临时关闭 systemctl stop firewall…

MySQL索引优化(超详细)篇章2--索引调优

目录 1.索引失效状况2.性能分析3.表的索引信息--调整索引顺序4.删除冗余索引5.最佳左前缀法则5.1下面是一个实际的例子来说明这个概念&#xff1a; 6.数据长度和索引长度占用空间比较 1.索引失效状况 MySQL索引失效通常指的是查询语句无法有效地利用索引&#xff0c;而导致全表…

微信登录功能--网站应用

微信开发平台注册https://open.weixin.qq.com/ 账号中心-填写基本资料&#xff08;最好是公司注册&#xff09; 账号中心-开发者资质认证&#xff08;充钱&#xff0c;300&#xff09; 审核通过之后&#xff0c;管理中心-网站应用-创建网站应用&#xff08;AppSecret一定一定…

国内十大免费图床推荐

国内十大免费图床推荐 近期&#xff0c;莫卡乐AI导航站汇总了国内一些出色的图床网站&#xff0c;既有知名大站&#xff0c;也有小众网站&#xff0c;用户的使用体验都非常好&#xff01; 1.路过图床 地址&#xff1a;https://imgse.com/ 我们是国内知名的图床之一&#xf…

Android 如何启用user版本的adb源码分析

通过adb shell中执行getprop persist.sys.usb.config&#xff0c;可以看到系统usb的相关选项&#xff0c;persist.sys.usb.config显示的就是当前系统关于usb选项的系统配置【RK3188Android4.4刚移植的例子】: 全编脚本中make命令会调用build/core/main.mk,在里面可以看到一段…

Ansible入门:解锁IT自动化的神

在当今的IT自动化领域&#xff0c;Ansible无疑是一个无法被忽视的重要角色。其便利性和高效性受到了广大开发者和系统管理员的一致好评&#xff0c;成为了配置管理和应用部署的首选工具。然而&#xff0c;对于一些初学者来说&#xff0c;Ansible的概念和架构可能会显得有些复杂…

微火全域外卖团购服务,引领商家与合伙人变革行业赛道!

在当今的数字化时代&#xff0c;外卖业务正成为越来越多人的日常生活选择。然而&#xff0c;随着市场的日益饱和和竞争的加剧&#xff0c;传统外卖模式已经难以满足商家和消费者的多元化需求。正是在这样的背景下&#xff0c;全域外卖团购业务应运而生&#xff0c;以其独特的模…

山东大学软件学院创新项目实训开发日志——第11周

山东大学软件学院创新项目实训开发日志——第11周 项目名称&#xff1a;ModuFusion Visionary&#xff1a;实现跨模态文本与视觉的相关推荐 -------项目目标&#xff1a; 本项目旨在开发一款跨模态交互式应用&#xff0c;用户可以上传图片或视频&#xff0c;并使用文本、点、…

使用Remix部署智能合约到币安链(Remix的操作介绍 币安链合约的部署) 点赞收藏哦

大家好&#xff0c;我是程序员大猩猩呀。 据我所知&#xff0c;很多人进入币圈之后&#xff0c;想要通过炒币一夜暴富&#xff01;另一部分人呢他们希望自己能创建一个项目&#xff0c;然后发行自己的数字货币然后暴富。 不管是什么方式吧&#xff0c;只要不违法&#xff0c;…

小程序第八章总结

1.比目后端云简介 一个完整的小程序系统, 不但需要前端的展现, 而且需要后端服务器的支撑, 以提供数据服务。 也就是说, 开发一个真正完整的小程序应用, 需要前后端的相互配合。 小程序与远程服务器之间通过&#xff28;&#xff34;&#xff34;&#xff30;&#xff33; 传输…

计算机组成结构—指令和指令格式

目录 一、指令的基本格式 二、指令字长 1. 定长指令字结构 2.变长指令字结构 三、地址码 1.四地址指令 2.三地址指令 3.二地址指令 4.一地址指令 5. 零地址指令 四、操作码 1. 定长操作码指令格式 2. 扩展操作码指令格式 五、指令的操作数类型和操作类型 1. 操作…

基于Python的数据分组技术:将数据按照1, 2, 3规则分为三个列表

目录 一、引言 二、数据分组原理与意义 三、案例分析 四、代码实现与解释 五、对新手友好的解释 六、技术细节与扩展 七、实际应用场景 八、总结 一、引言 在数据处理和分析的广阔领域中&#xff0c;数据分组是一项基础且重要的任务。数据分组通常指的是将数据集中的元…

程序员的归宿。。

大家好&#xff0c;我是瑶琴呀。 相信每个进入职场的人都考虑过自己的职业生涯规划&#xff0c;在不同的年龄段可能面临不同挑战&#xff0c;这点对于 35 的人应该更为感同身受。 对于程序员来说&#xff0c;大部分人的职业道路主要是下面三种&#xff1a;第一条&#xff0c;…

数据序列包分析

基于数据序列包分析各部分的内容及含义&#xff0c;可能会考大题 基于本例分析&#xff0c;每部分含义如下&#xff1a; 时间&#xff08;Time&#xff09;&#xff1a; 时间戳显示了数据包在网络中被捕获的具体时间。在本例中&#xff0c;如"0.000000"表示第一个数据…