作者:xyzZ
链接:https://www.zhihu.com/question/49656589/answer/117826278
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

.因为非原子性,volatile往往不能保证线程安全

.因为非原子性,volatile往往不能保证线程安全

.因为非原子性,volatile往往不能保证线程安全

volatile 只能保证 “可见性”,不能保证 “原子性”。

count++; 这条语句由3条指令组成:
(1)将 count 的值从内存加载到 cpu 的某个寄存器r
(2)将 寄存器r 的值 +1,结果存放在 寄存器s
(3)将 寄存器s 中的值写回内存

所以,如果有多个线程同时在执行 count++;,在某个线程执行完第(3)步之前,其它线程是看不到它的执行结果的。

在没有 volatile 的时候,执行完 count++;,执行结果其实是写到CPU缓存中,没有马上写回到内存中,后续在某些情况下(比如CPU缓存不够用)再将CPU缓存中的值flush到内存。正因为没有马上写到内存,所以不能保证其它线程可以及时见到执行的结果。
在有 volatile 的时候,执行完 count++;,执行结果写到CPU缓存中,并且同时写回到内存,因为已经写回内存了,所以可以保证其它线程马上看到执行的结果。
但是,volatile 并没有保证原子性,在某个线程执行(1)(2)(3)的时候,volatile 并没有锁定 count 的值,也就是并不能阻塞其他线程也执行(1)(2)(3)。可能有两个线程同时执行(1),所以(2)计算出来一样的结果,然后(3)存回的也是同一个值。

1.volatile不能保证原子性。简单说,java有所谓主内存区和线程栈,同一变量在主内存区和各个线程的栈都存在副本(一对多)。volatile提供的可见性,是说每个线程访问用volatile修饰的变量时,volatile都保证线程能从主存区加载到当前最新的值(反之,线程修改后同步到主存的值也要保证对其他线程的可见);

2.java的volatile的语义其实不涉及cpu缓存。jvm本身是软件抽象,已经在操作系统之上;

3.因为非原子性,volatile往往不能保证线程安全。如果只有简单读写操作如set i=2, get i, 可认为安全。i++就不行,它有一次读一次写;

4、volatile被认为是比锁要轻,编程要简单。

可以用volatile的地方:对一个变量,更新其值的时候不依赖于当前值,且该变量不会和其他一起构成一个不可变条件。

作者:卓尔不浪得
链接:https://www.zhihu.com/question/31990408/answer/54220910
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

java中关于volatile的理解疑问?的更多相关文章

  1. 你说一下对Java中的volatile的理解吧

    前言 volatile相关的知识其实自己一直都是有掌握的,能大概讲出一些知识,例如:它可以保证可见性:禁止指令重排.这两个特性张口就来,但要再往深了问,具体是如何实现这两个特性的,以及在什么场景下使用 ...

  2. 深入理解Java中的volatile关键字

    在再有人问你Java内存模型是什么,就把这篇文章发给他中我们曾经介绍过,Java语言为了解决并发编程中存在的原子性.可见性和有序性问题,提供了一系列和并发处理相关的关键字,比如synchronized ...

  3. Java中的volatile关键字的功能

    Java中的volatile关键字的功能 volatile是java中的一个类型修饰符.它是被设计用来修饰被不同线程访问和修改的变量.如果不加入volatile,基本上会导致这样的结果:要么无法编写多 ...

  4. java中线程同步的理解(非常通俗易懂)

    转载至:https://blog.csdn.net/u012179540/article/details/40685207 Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运 ...

  5. 一定要你明白Java中的volatile

    今天Tony来和大家聊聊Java中关键字volatile. 字节码 首先volatile int a = 3;和int a = 3;, 加不加volatile关键字,最终生成的字节码都一样的.有兴趣的 ...

  6. java中的volatile关键字

    java中的volatile关键字 一个变量被声明为volatile类型,表示这个变量可能随时被其他线程改变,所以不能把它cache到线程内存(如寄存器)中. 一般情况下volatile不能代替syn ...

  7. Java中线程同步的理解 - 其实应该叫做Java线程排队

    Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...

  8. java中的Volatile关键字使用

    文章目录 什么时候使用volatile Happens-Before java中的Volatile关键字使用 在本文中,我们会介绍java中的一个关键字volatile. volatile的中文意思是 ...

  9. [读书笔记]java中的volatile关键词

    以下内容大多来自周志明的<深入理解Java虚拟机>. 当一个变量被volatile修饰后,它将具备两种特性: 1. 保证此变量对所有线程的可见性,这里的“可见性”是指当一条线程修改了这个变 ...

随机推荐

  1. 使用node.js做一个自用的天气插件

    var request = require('request') var url = 'http://www.baidu.com/home/xman/data/superload' var cooki ...

  2. JSON对象与字符串之间的相互转换

    <html> <head> <meta name="viewport" content="width=device-width" ...

  3. C++ Primer读书笔记

    以前阅读学习C++ Primer时的习题代码(当时代码风格格式比较渣): https://github.com/liyuan989/exercise/tree/master/c%2B%2B%20pri ...

  4. Spring,tk-mapper源码阅读

    Mybatis的源码学习(一): 前言: 结合spring本次学习会先从spring-mybatis开始分析 在学习mybatis之前,应该要对spring的bean有所了解,本文略过 先贴一下myb ...

  5. python初学-列表

    列表操作: 列表一般需要先调用方法后才能打印,不能直接打印调用的方法 因为列表可以修改 一般不会返回一个新列表 # 列表 # new_names = ['lzc','lzc2','lzc3'] # 下 ...

  6. 虚拟机安装苹果系统 VMware 12安装Mac OS X 10.10

    工具/原料 VMware Workstation Pro 12 (这个可以自己下载,并激活,你懂得) Unlocker 207 (链接:http://pan.baidu.com/s/1i43obDb ...

  7. 《java并发编程实战》读书笔记11--构建自定义的同步工具,条件队列,Condition,AQS

    第14章 构建自定义的同步工具 本章将介绍实现状态依赖性的各种选择,以及在使用平台提供的状态依赖机制时需要遵守的各项规则. 14.1 状态依赖性的管理 对于并发对象上依赖状态的方法,虽然有时候在前提条 ...

  8. python类的使用与多文件组织

    多文件的组织 跨目录级导入模块 from ..xxfile import xxmodule #从上级目录中的xxfile中导入xxmodule import xxsub_dir.xxfile #从xx ...

  9. chattr命令的用法

    chattr (配置文件隐藏属性)[root@www ~]# chattr [+-=][ASacdistu] 文件或目录名称选项与参数:+ :添加某一个特殊参数,其他原本存在参数则不动.- :移除某一 ...

  10. Centos的 mysql for python的下载与安装

    mysql-python的安装包下载地址:http://sourceforge.net/projects/mysql-python/files/latest/download linux环境是 Cen ...