volatile重要特性-可见性,避免指令重排序-案例讲解
1.背景
volatile 修饰的作用????
什么是可见性??
什么是指令重排序??
2.可见性-案例
package com.my.aqs; /**
* @Copyright (C) XXXXX技有限公司
* @Author: ldp
* @Date: 2023/4/28 9:10
* @Description: <p>
* volatile 的可见性代码演示
* </p>
*/
public class Volatile021Demo {
// 如果a 没有 被 volatile 修饰,这里的a是 [不可见的] ,[不可以] 读取到其他线下修改后的值, 即从[工作]内存中读取==> 产生死循环
// 如果a 被 volatile 修饰,这里的a是 [可见的] ,[可以]读取到其他线下修改后的值, 即从[主]内存中读取 ==> 不会产生死循环
// static volatile int a, b;
static int a, b; /**
* 指令重排序测试
*
* @param args
*/
public static void main(String[] args) throws InterruptedException {
// 线程A
Thread threadA = new Thread(() -> {
a = 1;
System.out.println("A执行完成:" + a);
});
// 线程B
Thread threadB = new Thread(() -> {
// 如果a 没有 被 volatile 修饰,这里的a是 [不可见的] ,[不可以] 读取到其他线下修改后的值, 即从[工作]内存中读取==> 产生死循环
// 如果a 被 volatile 修饰,这里的a是 [可见的] ,[可以]读取到其他线下修改后的值, 即从[主]内存中读取 ==> 不会产生死循环
while (a == 0) {
try {
// System.out.println("等待中===="); // 就算不添加volatile 修饰a, 执行输出语句后a会重新从主内存中读取
// System.out.println("当前a==>:" + a);
// Thread.sleep(500);// 就算不添加volatile 修饰a, 执行输sleep后a会重新从主内存中读取
b = a; // 不会导致从主内存中读取
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("B执行完成:" + a);
});
threadB.start();
// 让B线程先执行
Thread.sleep(50);
threadA.start();
while (threadA.isAlive() || threadB.isAlive()) {
}
System.out.println("main执行完成:" + a);
}
}
3.避免指令重排序-案例
package com.my.aqs; import java.util.HashSet;
import java.util.Set; /**
* @Copyright (C) XXXXX技有限公司
* @Author: ldp
* @Date: 2023/4/28 15:03
* @Description:
*/
public class Volatile03Demo {
// static volatile int a, b, A, B;
static int a, b, c, d; /**
* 指令重排序-案例演示
* <p>
* 如果:下面的代码,如果不考虑 指令重排序的问题, c和d永远都不会同时为0;
* 但是:因为在没有volatile修饰的情况下,可能会产生指令重排序,因此会产生 指令重排序,
* 导致
* t1线程中先执行 c = b;
* t2线程中先执行 d = a;
* 这两行代码先执行,从而导致c 和 d同时为0;
*
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
long num = 0;
Set<String> ABSet = new HashSet<>(8);
while (true) {
num++;
a = 0;
b = 0;
c = 0;
d = 0;
Thread t1 = new Thread(() -> {
a = 1;
c = b;
});
Thread t2 = new Thread(() -> {
b = 1;
d = a;
});
t1.start();
t2.start();
t1.join();
t2.join();
ABSet.add("a=" + a + "|b=" + b + "|c=" + c + "|d=" + d);
if (c == 0 && d == 0) {
System.out.println("a=" + a + "|b=" + b + "|c=" + c + "|d=" + d);
System.out.println("num=" + num);
System.out.println(ABSet);
break;
}
}
}
}
完美!
volatile重要特性-可见性,避免指令重排序-案例讲解的更多相关文章
- JVM并发机制的探讨——内存模型、内存可见性和指令重排序
并发本来就是个有意思的问题,尤其是现在又流行这么一句话:“高帅富加机器,穷矮搓搞优化”. 从这句话可以看到,无论是高帅富还是穷矮搓都需要深入理解并发编程,高帅富加多了机器,需要协调多台机器或者多个CP ...
- 轻松学JVM(二)——内存模型、可见性、指令重排序
上一篇我们介绍了JVM的基本运行流程以及内存结构,对JVM有了初步的认识,这篇文章我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存 ...
- JVM学习--(二)内存模型、可见性、指令重排序
我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存模型 首先我们思考一下一个java线程要向另外一个线程进行通信,应该怎么做,我们再 ...
- 深入理解JVM(二)——内存模型、可见性、指令重排序
上一篇我们介绍了JVM的基本运行流程以及内存结构,对JVM有了初步的认识,这篇文章我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存 ...
- 深入理解JVM一内存模型、可见性、指令重排序
一.内存模型 首先我们思考一下一个java线程要向另外一个线程进行通信,应该怎么做,我们再把需求明确一点,一个java线程对一个变量的更新怎么通知到另外一个线程呢?我们知道java当中的实例对象.数组 ...
- 内存可见性,指令重排序,JIT。。。。。。从一个知乎问题谈起
在知乎上看到一个问题<java中volatile关键字的疑惑?>,引起了我的兴趣 问题是这样的: package com.cc.test.volatileTest; public clas ...
- 关于volatile的可见性和禁止指令重排序的疑惑
在学习volatile语义的可见性和禁止指令重排序的相关测试中,发现并不能体现出禁止指令重排序的特性 实验代码如下 package com.aaron.beginner.multithread.vol ...
- 使用 volatile 关键字保证变量可见性和禁止指令重排序
volatile 概述 volatile 是 Java 提供的一种轻量级的同步机制.相比于传统的 synchronize,虽然 volatile 能实现的同步性要差一些,但开销更低,因为它不会引起频繁 ...
- Java的多线程机制系列:不得不提的volatile及指令重排序(happen-before)
一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...
- Java的多线程机制系列:(四)不得不提的volatile及指令重排序(happen-before)
一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...
随机推荐
- transformer原理
Transformer注意力架构原理 输入层 embedding词嵌入向量 将文本中词汇的数字表示转变为向量表示,在这样的高维空间捕捉词汇间的关系 语义相近的词语对应的向量位置也更相近 每个词先通过词 ...
- Controller-runtime模块
Controller-runtime框架 Controller-runtime是社区提供的用于开发Controller的框架,包含了各种已封装的代码库.Kubebuilder与Operator SDK ...
- CANoe创建仿真工程
在现代汽车工业中,车载测试是确保车辆电子系统可靠性和功能性的关键环节.而使用CANoe创建仿真工程,不仅能够模拟真实的车辆环境,还能大大提升测试效率和准确性.那么,CANoe是如何实现这些的呢? 车载 ...
- Vue2 整理(一):基础篇
前言 首先说明:要直接上手简单得很,看官网熟悉大概有哪些东西.怎么用的,然后简单练一下就可以做出程序来了,最多两天,无论Vue2还是Vue3,就都完全可以了,Vue3就是比Vue2多了一些东西而已,所 ...
- 韦东山freeRTOS系列教程之【第十章】软件定时器(software timer)
目录 系列教程总目录 概述 10.1 软件定时器的特性 10.2 软件定时器的上下文 10.2.1 守护任务 10.2.2 守护任务的调度 10.2.3 回调函数 10.3 软件定时器的函数 10.3 ...
- 记录一次python3 flask 多线程被执行两次的问题
前言 最近在使用 python3 flask 做管理服务,需要实现服务中 flask server 和 另一个多线程while循环同时存在,如下 from flask import Flask , j ...
- 洛谷P1003
洛谷P1003 题目大意 简而言之就是在坐标轴上铺地毯,根据输入的坐标将地毯放在坐标轴上,然后最后给出一个坐标,找到铺在这个坐标上最上面的地毯编号 Train of thought 首先我们应该找到每 ...
- 记一次 CDN 流量被盗刷经历
先说损失,被刷了 70 多RMB,还好止损相对即时了,亏得不算多,PCDN 真可恶啊. 600多G流量,100多万次请求. 怎么发现的 先是看到鱼皮大佬发了一篇推文突发,众多网站流量被盗刷!我特么也中 ...
- 2024秋招字节跳动朝夕光年UE4客户端开发实习生岗笔试题目
20240117更新 2024年秋招笔试题目,没想到时隔几个月字节跳动游戏业务就要寄了,本文仅供参考,请大佬多多指教 Q1字符串处理 Q2 杯子问题 桌子上有4109+1个饮料杯,这些饮料杯的编号依次 ...
- Python 基于xml.etree.ElementTree实现XML对比
测试环境 Python 3.6 Win10 代码实现 #!/usr/bin/env python 3.4.0 #-*- encoding:utf-8 -*- __author__ = 'shouke' ...