首页 > 其他分享 >证明volatile的可见性和原子性

证明volatile的可见性和原子性

时间:2023-04-12 21:03:32浏览次数:15  
标签:同步 变量 可见 原子 线程 使用 volatile


证明volatile的可见性和原子性_同步机制

 volatile作用

  • 保证内存可见性
  • 防止指令重排序
  • 注意:并不保证原子性

可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值

内存可见性

volatile保证可见性的原理是在每次访问变量时候都会进行一次刷新,因此每次访问都是准没存中最新的版本,所以volatile关键字的作用之一就是保证变量修改的实时可见性

使用volatile使用必须的条件

  1. 对变量的写入操作不依赖变量的当前值,或者你能确保只有单个线程更新变量的值
  2. 该变量没有包含在具有其他变量的不变式中

volatile使用建议

  • 在两个或者更多的线程需要访问的成员变量上使用volatile,当腰访问的变量已在shnchronized代码块中或者常量时,咱们就没要使用volatile
  • 由于使用volatile屏蔽调JVM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字

volatile和synchronized区别

1:volatile不会进行枷锁操作,volatile变量是一种微弱的同步机制在访问volatile变量时不会执行解锁操作,因此不会执行线程阻塞,因此volatile变量是一种比synchronized关键字更轻量级的同步机制。

2:volatile变量作用类似于同步变量读写操作,从内存可见性的角度来看,写入volatile变量相当于退出同步代码块,而读取volatile比那辆相当于进入同步代码块。

3:volatile不如synchronized安全,在代码中如果过度使用volatile变量来控制状态的可见性,通常会比使用锁的代码更脆弱,也更难以理解,仅当volatile变量能简化代码的实现以及对同步策略的验证时,才应该使用volatile,一般来说,使用同步机制会更安。

4:volatile无法同事保证内存可见性和原子性,加锁机制(同步机制)既可以确保可见性又可以确保原子性,而volatile只能保证可见性,原因是声明为volatile的简单变量如果昂墙纸与该变量以前的值相关,那么volatile关键字不起作用,也就是说下面的表达式都不是院子操作的:count++,i++。

可见性demo证明

证明volatile的可见性和原子性_同步机制_02

输出,一直执行中,证明这个一个线程修改后其他线程并不知道,导致while循环一直执行

证明volatile的可见性和原子性_同步机制_03

给quit变量加一个volatile修饰

证明volatile的可见性和原子性_可见性_04

输出

证明volatile的可见性和原子性_同步机制_05

不保证原子性demo证明


证明volatile的可见性和原子性_内存可见性_06

输出结果多变: 

第一种结果

证明volatile的可见性和原子性_内存可见性_07

第二种结果

证明volatile的可见性和原子性_同步机制_08

第三种

证明volatile的可见性和原子性_可见性_09

第四种

证明volatile的可见性和原子性_可见性_10

标签:同步,变量,可见,原子,线程,使用,volatile
From: https://blog.51cto.com/u_11702014/6186217

相关文章

  • volatile关键字
    在C和C++中,volatile关键字用于告诉编译器某些特定的变量可能会在无意中被修改,从而防止编译器优化掉相关代码。当我们使用声明为volatile类型的变量时,表示变量的值是随时可能发生变化的,并且需要特别小心地处理。主要有以下几种情况需要使用volatile关键字:位域当使用volatile关......
  • atomic原子类
    原子类介绍java.util.concurrent.atomicjava并发包下的类,用于多线程情况下保证线程安全的API基本类型原子类AtomicInteger数组类型原子类AtomicIntegerArray引用类型原子类AtomicReference对象的属性修改原子类AtomicIntegerFieldUpdate原子操作增......
  • volatile关键字
    volatile是java虚拟机提供的轻量级的同步机制内存可见性(保证可见性)不保证原子性禁止指令重排(保证有序性)可见性volatile修饰的共享变量有如下特点线程中读取这个变量时,每次都会读取主内存中最新的值,然后将其复制到工作内存线程中修改了工作内存中变量的副本,修改......
  • 8.0的新特性 -- invisible(不可见索引)
    版权声明:原创作品,谢绝转载!否则将追究法律责任。—————作者:kirininvisibleindex不可见索引以前的版本,假如这个索引无用了会怎么样?那就只能是drop掉了。但是drop掉的话可能会产生一个比较严重问题。比如说万一这个索引还有用的话,那整个业务就会慢下来,所以说风险还是比较大......
  • 8.0的新特性 -- invisible(不可见索引)
    版权声明:原创作品,谢绝转载!否则将追究法律责任。—————作者:kirininvisibleindex不可见索引以前的版本,假如这个索引无用了会怎么样?那就只能是drop掉了。但是drop掉的话可能会产生一个比较严重问题。比如说万一这个索引还有用的话,那整个业务就会慢下来,所以说风险还是比较大......
  • CAS & volatile
    1.CAS1.1问题在JDK5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁锁机制存在以下问题:(1)在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。(2)一个线程持有锁会导致其它所有需要此锁的线程挂起。(3)如果一个优先级高的线程等待一个优......
  • 学了这么久的高并发编程,连Java中的并发原子类都不知道?
    摘要:保证线程安全是Java并发编程必须要解决的重要问题,本文和大家聊聊Java中的并发原子类,看它如何确保多线程的数据一致性。本文分享自华为云社区《学了这么久的高并发编程,连Java中的并发原子类都不知道?这也太Low了吧》,作者:冰河。今天我们一起来聊聊Java中的并发原子类。在 j......
  • 【Java 并发】【八】【Atomic】【一】JUC下的Atomic原子类体系概览
    1 前言这节我们就开始看看Atomic原子类系列,JUC包下提供的原子类底层的实现原理基本都是差不多的,都是基于volatile和CAS操作来保证线程安全的,我们后续会着重分析几个类。2  概览我们看下JUC下边都有哪些原子类:看上面的图形,我们使用红色圈中的那些,就是我们要着重讨论的,一共......
  • 【Java 并发】【五】volatile怎么通过内存屏障保证可见性和有序性
    1 前言这节我们就来看看volatile怎么通过内存屏障保证可见性和有序性。2  保证可见性volatile修饰的变量,在每个读操作(load操作)之前都加上Load屏障,强制从主内存读取最新的数据。每次在assign赋值后面,加上Store屏障,强制将数据刷新到主内存。以volatileintx=0;线程A、B进行......
  • mutable、const、volatile关键字
    C++中有三种修饰数据可变的关键字:mutable、const、volatile。constconst我们很常见,在定义一些不可变的常量或不修改数据内容的函数时经常会用到。 修饰变量,说明该变量不可以被改变;修饰指针,分为指向常量的指针(例如constchar*,其自身可变,指向的是常量字符数组)和自身是常量的......