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

【JUC】11-volatile关键字

1. volatile关键字修饰变量特点

 不支持原子性。

  • 可见性:对一个被volatile关键字修饰的变量,1. 写操作,这个变量的最新值会立即刷新回到主内存中。 2. 读操作,总是能够读取到这个变量的最新值,也就是这个变量最后被修改的值。 3. 当某个线程收到通知,去读取volatile修饰的变量的值的时候,线程私有工作内存的数据失效,需要重新回到主内存中读取最新的数据。
  • 有序性:有时需要禁止重排序。

2. volatile内存语义

  • 当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值立即刷新回主内存中。
  • 当读一个volatile变量时,JMM会把该线程对应的本地内存设置为无效,重新回到内存中读取最新共享变量。
  • 所以volatile的写内存语义是直接刷新到主内存中,读的内存语义是直接从内存中读取。

3. volatile内存屏障

写屏蔽:写屏蔽之前的所有写操作都要写回到主内存。
读屏蔽:读屏蔽之后的所有读操作都在读屏蔽之后执行,都可以读到最新数据。在这里插入图片描述

4. 指令重排

在这里插入图片描述

5. volatile的可见性

public class demo04 {/* volatile 可以让数据将线程中的数据副本更新到主内存中去掉 volatile, 子线程中的 flag 会一直自己的数据副本, 不会进行更新*/static volatile boolean flag = true;public static void main(String[] args) {new Thread(()->{System.out.println("thread start");while (flag) {}System.out.println("exit");}).start();try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {throw new RuntimeException(e);}flag = false;System.out.println("flag update: "+flag);}
}

 volatile加锁与解锁的过程。在这里插入图片描述

6. volatile无原子性

 volatile不能保证同一时刻,对于同一份数据,只有一个线程操作。volatile适合与布尔类型和int类型。
 一下i++的例子证明volatile无原子性。

class Number {// 使用volatile结果输出并不稳定唯一volatile int num;public void add() {num ++;}public int get(){return num;}
}public class demo05 {public static void main(String[] args) {Number number = new Number();for(int i=0; i<10; i++) {new Thread(()->{for (int j = 0; j < 100; j++) {number.add();}}).start();}try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(number.get());}
}

7. volatile禁止重排

双重检查锁定(Double-Checked Locking, DCL)的单例模式:

public class SafeDoubleCheckSingleton {private static volatile SafeDoubleCheckSingleton singleton;private SafeDoubleCheckSingleton() {}public static SafeDoubleCheckSingleton getInstance() {if (singleton == null) {synchronized (SafeDoubleCheckSingleton.class) {if (singleton==null) {/*** singleton 实例化:分配内存空间、初始化对象、将对象指向分配的内存空间* JMM 可能会进行指令重排: 分配内存空间、将对象指向分配的内存空间、初始化对象* 多线程场景下, 会出现问题* 为 singleton 添加 volatile 关键字, 可解决这个问题*/singleton = new SafeDoubleCheckSingleton();}}}return singleton;}
}

http://www.mrgr.cn/news/19671.html

相关文章:

  • 步进、闭环、交流伺服三类电机驱动方案对比
  • springboot-es(elasticsearch)搜索项目
  • Elasticsearch设置密码报错:ERROR: X-Pack Security is disabled by configuration.
  • 汽车电子行业知识:关于车载中控屏
  • 深度学习--机器学习相关(2)
  • 推荐一款好用的局域网文件传输工具
  • 轻NAS系统CasaOS设备安装Memos笔记结合内网穿透公网访问与同步教程
  • leetcode 1645 Hopper公司查询2(postgresql)
  • 浙大数据结构:02-线性结构1 两个有序链表序列的合并
  • bootstrapValidator 动态添加控件 并绑定验证
  • 10.7 URL
  • 【数据结构】排序算法系列——序言(附源码+图解)
  • 羊大师:白露养生经,羊奶不可少
  • JMeter:如何定制Http请求取样器
  • QGraphicsView、QGraphicsScene和QGraphicsItem图形视图框架(一)简单介绍
  • 揭秘ECMAScript与JavaScript:掌握编程世界的基石与实践!
  • k8s介绍
  • 9/4 链表-力扣 234、19
  • 学习之SQL语句之DQL(数据库查询语言)
  • 项目管理软件助力研发团队:从规划到交付的无缝衔接