voliate实战:voliate可见性验证有序性非原子性验证

一、可见性验证

下面的程序验证了voliate的可见性。

public class VolatileVisibilityTest {private static volatile boolean inintFlag = false;public static void main(String[] args) throws InterruptedException {new Thread(() -> {System.out.println("waiting data...");while (!inintFlag){}System.out.println("===============success");}).start();Thread.sleep(2000);new Thread(() -> prepareData()).start();}public static void prepareData(){System.out.println("prepare data.....");inintFlag = true;System.out.println("prepare data end....");}
}

代码执行过程如下:
在这里插入图片描述

在这里插入图片描述

  • voliate可见性的底层实现原理
    通过程序执行的汇编指令发现,是通过锁机制实现的。

验证过程

  • 下载反汇编程序插件
    下载地址:https://download.csdn.net/download/luckywuxn/88347740
  • 插件配置
    将hsdis-amd64.dll放在 $JAVA_HOME/jre/bin/server 目录下
  • idea中设置启动参数
    -server -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=compileonly,*VolitaleDemo.main
  • 启动程序查看结果
    控制台搜索lock关键字,将看到如下结果,结果现在lock指令执行的程序是在源代码的第28行。
    在这里插入图片描述

二、有序性

  • 示例一
public class VolatileSerialTest {static int x = 0,y = 0;static int a = 0,b = 0;public static void main(String[] args) throws InterruptedException {long startTime = System.currentTimeMillis();for (int i = 0;; i ++){x = 0;y = 0;a = 0;b = 0;Thread one = new Thread(() -> {a = y;x = 1;});Thread other = new Thread(() -> {b = x;y = 1;});one.start();other.start();one.join();other.join();if (a == 1 && b == 1){long endTime = System.currentTimeMillis();System.out.println("经过" + (endTime - startTime) + "ms," + i + "次之后a=b=1");break;}System.out.println("当前执行" + i + "次");}}
}

运行上面代码,得到以下结果,由此我们可以得到结论,在没有使用voliate关键字时,两个线程中的两条指令是可以重排序的。
在这里插入图片描述

  • 示例二
public class VolatileSerialTest2 {private static VolatileSerialTest2 instance = null;private VolatileSerialTest2(){}public static VolatileSerialTest2 getInstance(){if (instance == null){synchronized (VolatileSerialTest2.class){if (instance == null){instance = new VolatileSerialTest2();}}}return instance;}public static void main(String[] args) {VolatileSerialTest2 instance = VolatileSerialTest2.getInstance();}}

编译之后,通过idea插件jclasslib插件可以看到字节码文件如下
在这里插入图片描述
由JMM规范可知,如果第11、12行是最新as-if-serial & happens-before 原则的,所有这两条指令是可能重排序的,为了防止重排序,我们只需要加上voliate关键字就可以了。

三、原子性验证

下面是一个原子性验证的代码:

class Counter {private volatile int count = 0;public void increment() {count++;}public int getCount() {return count;}
}public class VolatileAtomicTest {public static void main(String[] args) {final Counter counter = new Counter();// 创建两个线程,同时递增计数器的值Thread thread1 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});thread1.start();thread2.start();// 等待两个线程执行完成try {thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}// 输出最终的计数器值System.out.println("Final Count: " + counter.getCount());}
}

运行上面代码,结果如下
在这里插入图片描述
上面程序使用两个线程同时对voliate修饰的变量count进行累计操作,voliate对所有线程都是可见的,那为什么结果不是2000呢,这是由于voliate修饰的变量并不是原子的。

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

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

相关文章

期权投资的优势有哪些方面?

随着金融市场的不断演变&#xff0c;越来越多的金融衍生品出现在人们的视线中&#xff0c;特别是上证50ETF期权可以做空T0的交易模式吸引了越来越多的朋友&#xff0c;那么期权投资的优势有哪些方面&#xff1f; 期权是投资市场中一个非常重要的投资方式&#xff0c;期权投资能…

LeetCode:两数之和

题目描述&#xff1a; 这是一道用暴力解法&#xff0c;逻辑十分简单、清晰的一道题&#xff0c;直接遍历数target-num[i]就行 而官方给了第二种巧妙的解法&#xff1a;运用哈希表。此法可将时间复杂度从O&#xff08;N^2&#xff09;降到O&#xff08;1&#xff09; 其思路是…

日志技术-Logback

日志技术 将系统执行的信息&#xff0c;方便的记录到指定位置&#xff08;控制台、文件、数据库&#xff09;可以随时以开关的形式开关日志&#xff0c;无需入侵到源代码去修改 日志接口&#xff1a;设计日志框架的统一标准 注&#xff1a;有人对JCL接口不满意&#xff0c;就…

基于Questasim的SystemVerilog DPI使用流程

1. 前言 DPI是Direct Programming Interface的缩写&#xff0c;它提供了SystemVerilog与其它编程语言(特别是C语言)交互的接口。它允许编程人员轻松地从SystemVerilog调用C函数&#xff0c;且在C函数也可以调用Systemverilog的函数。 DPI极大地方便了使用现有的C代码&#xf…

深度学习-全连接神经网络-激活函数- [北邮鲁鹏]

文章目录 基础知识为什么需要非线性操作&#xff08;激活函数&#xff09;&#xff1f;激活函数 vs 数据预处理常用的激活函数Sigmoid函数 &#xff08;Logistic函数&#xff09;双曲正切函数&#xff08;Tanh函数&#xff09;线性整流函数&#xff08;ReLU函数&#xff09;Lea…

C【数组】

1.一维数组 1.1 数组的创建 1.2 数组的初始化 1.3 一维数组的使用 int main() { // char arr[] "abcdef";//[a][b][c][d][e][f][\0] // //printf("%c\n", arr[3]);//d // int i 0; // int len strlen(arr); // for(i0; i<len; i) // { // p…

机器学习笔记之最优化理论与方法(十)无约束优化问题——共轭梯度法背景介绍

机器学习笔记之最优化理论与方法——共轭梯度法背景介绍 引言背景&#xff1a;共轭梯度法线性共轭梯度法共轭方向共轭VS正交共轭方向法共轭方向法的几何解释 引言 本节将介绍共轭梯度法&#xff0c;并重点介绍共轭方向法的逻辑与几何意义。 背景&#xff1a;共轭梯度法 关于…

Ubuntu 22.04LTS + 深度学习环境安装全流程

一、 CUDA Toolkit 安装 1. 选择需要安装的版本(下载地址) 2. 选择自己的系统版本获取下载地址和安装指令 3. 运行安装指令进行安装 wget https://developer.download.nvidia.com/compute/cuda/12.2.2/local_installers/cuda_12.2.2_535.104.05_linux.run sudo sh cuda_12.2.…

Docker Swarm集群部署

Docker Swarm集群部署 任务平台 3台虚拟机&#xff0c;一台作为manager 节点&#xff0c;另两台作为work节点。 文章目录 Docker Swarm集群部署安装docker配置防火墙开放端口在 manager 节点创建 Swarm 集群创建用于swarm服务的自定义的overlay网络测试跨主机容器通信 安装do…

网上办公系统设计与实现

目录 前言 1问题定义 1.1系统名称 1.2系统背景 1.3系统目标 2 可行性分析 2.1 经济可行性 2.2 技术可行性 2.3 操作可行性 2.4 法律可行性 2.5 可行性研究结论 2.6 用户组织机构图 2.7 目标系统业务流程图 2.8 接口设计 2.8.1外部接口 2.8.2 内部接口 3 需求分…

Centos7.9 一键脚本部署 LibreNMS 网络监控系统

前言&#xff1a; LibreNMS 是个以 PHP/MySQL 为基底的自动探索网络监控系统 LibreNMS 官网 版本23.8.2-52-g7bbe0a2 - Thu Sep 14 2023 22:33:23 GMT0700数据库纲要2023_09_01_084057_application_new_defaults (259)Web 服务器nginx/1.20.1PHP8.1.23Python3.6.8DatabaseMa…

Postman的高级用法一:重新认识postman核心模块

本请求示例来自于免费天气API&#xff1a; 实况天气接口API开发指南 未来一天天气预报api - 天气API 关于Postman的核心模块 全局变量请求接口请求体预处理脚本 类似beforeTest&#xff0c;在发起请求前的预执行逻辑&#xff0c;通常是生成一些动态变量值 测试用例模块 测试者…

PhpStorm 2023年下载、安装教程和好用插件,保姆级教程

PhpStorm 2023年下载、安装教程和好用插件&#xff0c;保姆级教程 文章目录 PhpStorm 2023年下载、安装教程和好用插件&#xff0c;保姆级教程前言一、安装PhpStorm二、好用的插件简体中文包Chinese(Simplified)Language Pack 三、卸载插件CTRLN 查找类CTRLSHIFTN 全局搜索文件…

Visual Studio复制、拷贝C++项目与第三方库配置信息到新的项目中

本文介绍在Visual Studio软件中&#xff0c;复制一个已有的、配置过多种第三方库的C项目&#xff0c;将其拷贝为一个新的项目&#xff0c;同时使得新项目可以直接使用原有项目中配置好的各类**C**配置、第三方库等的方法。 在撰写C 代码时&#xff0c;如果需要用到他人撰写的第…

Linux学习第16天:Linux设备树下的LED驱动开发:举一反三 专注专心专业

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 在开题之前&#xff0c;先说一下这次的题目&#xff0c;尤其是后面的“举一反三 专注专心专业”到底想给大家传递什么信息。LED驱动开发&#xff0c;目前为止已经…

深入思考redis面经

1 redission分布式锁 1.1 为了保证数据一致性&#xff0c;引入了redission的锁&#xff0c;你是为了抗住高并发而去为了引入这个锁还是说为了保证数据一致性去引入的 答&#xff1a;主要是为了抗住高并发问题&#xff0c;解决redis的缓存击穿问题&#xff0c;但是也能解决一定…

Vue系列之入门篇

前言&#xff1a; 目录 一&#xff0c;关于Vue的简介 1.什么是Vue&#xff1f; 2.使用Vue框架的好处&#xff1f; 3. 库和框架的区别&#xff1a; 4. MVVM的介绍 5.Vue的入门案例 二&#xff0c;Vue的生命周期 一&#xff0c;关于Vue的简介 1.什么是Vue&#xff1f; Vu…

YSA Toon (Anime/Toon Shader)

这是一个Toon着色器/Cel阴影着色器,用于Unity URP 此着色器的目的是使角色或物体阴影实时看起来尽可能接近真实的动画或卡通效果 可以用于游戏,渲染,插图等 着色器特性,如:面的法线平滑、轮廓修复、先进的边缘照明、镜面照明、完全平滑控制 这个文档包括所有的功能https:/…

【数据结构前置知识】初识集合框架和时间,空间复杂度

文章目录 1. 什么是集合框架2. 集合框架的重要性 3. 背后所涉及的数据结构以及算法3.1 什么是数据结构3.2 容器背后对应的数据结构3.3 相关java知识3.4 什么是算法 4.时间复杂度1. 如何衡量一个算法的好坏2. 算法效率3. 时间复杂度3.1 时间复杂度的概念3.2 大O的渐进表示法3.3 …

在项目中,关于前端实现数据可视化的技术选择

前言 在项目中&#xff0c;数据可视化以图表、报表类型为主。 需求背景 技术框架是Vue2.x版本&#xff0c;组件库是Ant Design of Vue能够支撑足够多的图表类型开发图表大小/位置能够随意变动图表样式需要支持丰富多样的用户配置强大、开放的图表语法支持复杂的数据可视化场景…