原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11426473.html

关键字volatile的主要作用是使变量在多个线程间可见,但无法保证原子性,对于多个线程访问同一个实例变量需要加锁进行同步。

 package org.fool.java.concurrent.volatiletest;  

 import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class VolatileTest1 { private static volatile int count = 0; private static void addCount() {
for (int i = 0; i < 100; i++) {
count++;
} System.out.println(Thread.currentThread().getName() + " count = " + count);
} public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool(); for (int i = 0; i < 100; i++) {
executor.execute(new Runnable() {
@Override
public void run() {
VolatileTest1.addCount();
}
});
} executor.shutdown();
}
}

Note:

addCount()方法没有加synchronized

Console Output

预期结果应该是10000,尽管count被volatile修饰,保证了可见性,但是count++并不是一个原子性操作,它被拆分为load、use、assign三步,而这三步在多线程环境中,use和assgin是多次出现的,但这操作是非原子性的,也就是在read和load之后,如果主内存count变量发生修改之后,线程工作内存中的值由于已经加载,不会产生对应的变化,也就是私有内存和公有内存中的变量不同步,所以计算出来的值和预期不一样,就产生了线程安全的问题,所以需要用synchronized进行加锁同步

addCount()方法用synchronized进行加锁同步

Console Output

结果10000与预期一致

所以volatile只能保证可见性不能保证原子性,但用volatile修饰long和double可以保证其操作原子性

所以从Oracle Java Spec里面可以看到:

  • 对于64位的long和double,如果没有被volatile修饰,那么对其操作可以不是原子的。在操作的时候,可以分成两步,每次对32位操作。
  • 如果使用volatile修饰long和double,那么其读写都是原子操作
  • 对于64位的引用地址的读写,都是原子操作
  • 在实现JVM时,可以自由选择是否把读写long和double作为原子操作
  • 推荐JVM实现为原子操作

Reference

http://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.7

http://www.cnblogs.com/louiswong/p/5951895.html

http://ifeve.com/volatile/

http://www.infoq.com/cn/articles/java-memory-model-4/

Java中volatile如何保证long和double的原子性操作的更多相关文章

  1. java中volatile不能保证线程安全

    今天打了打代码研究了一下java的volatile关键字到底能不能保证线程安全,经过实践,volatile是不能保证线程安全的,它只是保证了数据的可见性,不会再缓存,每个线程都是从主存中读到的数据,而 ...

  2. Java中Volatile关键字详解

    一.基本概念 先补充一下概念:Java并发中的可见性与原子性 可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值, ...

  3. java中volatile

    volatile用来修饰变量.Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 synchronized 块相比,volat ...

  4. java中volatile关键字的理解

    一.基本概念 Java 内存模型中的可见性.原子性和有序性.可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有 ...

  5. Java中Volatile关键字详解(转载)

    转载自:https://www.cnblogs.com/zhengbin/p/5654805.html 一.基本概念 先补充一下概念:Java 内存模型中的可见性.原子性和有序性. 可见性: 可见性是 ...

  6. Java中Volatile关键字详解 (转自郑州的文武)

    java中volatile关键字的含义:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 一.基本概念 先补充一下概念:J ...

  7. 【转】java中volatile关键字的含义

    java中volatile关键字的含义   在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...

  8. 转:java中volatile关键字的含义

    转:java中volatile关键字的含义 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...

  9. Java中Volatile的作用

    Java中Volatile的作用 看了几篇博客,发现没搞懂.可是简单来说,就是在我们的多线程开发中.我们用Volatile关键字来限定某个变量或者属性时,线程在每次使用变量的时候.都会读取变量改动后的 ...

随机推荐

  1. css linear-gradient;心跳animation

    css线性背景 background:linear-gradient(20deg,#ccffff,#ffcccc); transform transform:scale(1.5); transform ...

  2. 【HDOJ6595】Everything Is Generated In Equal Probability(期望DP)

    题意:给定一个N,随机从[1,N]里产生一个n, 然后随机产生一个n个数的全排列,求出n的逆序数对的数量并累加ans, 然后随机地取出这个全排列中的一个子序列,重复这个过程,直到为空,求ans在模99 ...

  3. 【BZOJ3522&BZOJ4543】Hotel加强版(长链剖分,树形DP)

    题意:求一颗树上三点距离两两相等的三元组对数 n<=1e5 思路:From https://blog.bill.moe/bzoj4543-hotel/ f[i][j]表示以i为根的子树中距离i为 ...

  4. nIce 不看会后悔的o!

    今天小编来跟大家探讨关于“控件”.控件非常好玩,可以构建出不同的场景和不同风格的Windows画面.相信大家绝对狠感兴趣是吧~~~   好了,下面小编就为大家来展示风采喽 下面先为大家展示一些比较基础 ...

  5. CMMI模型

    CMMI的成熟度级别 初始级(过程不可预测,管理和控制差,是反应式的)管理级(过程处于项目级,经常是反应式的)定义级(过程已经提升到组织级(OSSP))定量管理级(对过程进行度量,并进行统计控制)优化 ...

  6. gym 101810 M. Greedy Pirate (LCA)

    题目:https://codeforc.es/gym/101810/problem/M 题意:给 你一颗树,下面有m次查询,求u->v的最大值是多少,输入两点之间都会有两条边,正边有正权,反边有 ...

  7. CSS基础知识复习

    1. CSS优先级 标签内部属性 style定义的CSS > 文档内定义的css > 引用外部CSS文件 2. CSS选择器类型 . 标签选择器 . 类选择器(使用.做标识) . ID选择 ...

  8. Spring Boot学习一之Spring Beans和依赖注入

    你可以自由地使用任何标准的Spring框架技术去定义beans和它们注入的依赖.简单起见,我们经常使用 @ComponentScan 注解搜索beans,并结合 @Autowired 构造器注入. 如 ...

  9. poj-1021--2D-Nim--点阵图同构

    2D-Nim Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4136   Accepted: 1882 Descriptio ...

  10. Frida Android hook native层__system_property_get的最终方案

    记录这个问题的起因是,在hook时遇到了修改内容长度,超过原长度时,会出现显示不全的问题. 比如把nexus 5改成nexus 100,只会显示nexus 1. 所以去读了下源码 int __syst ...