Java中primite type,如char,integer,bool之类的,它们的读写操作都是atomic的,但是有几个例外:

  1. long和double类型不是atomic的,因为long和double都是8字节的,而在32位的CPU上,其机器字长为32位,操作8个字节需要多个指令操作。
  2. ++i或者i++,因为要先读后写,也是多步操作。

这些情况下,需要使用AutomicInteger,AutomicLong。

同时,java中的reference的读写也是automic的,虽然reference到底占几个字节没有明确定义,但至少以下可以保证:

  1. 在32位的CPU下,使用的是4字节的reference
  2. 在64位的CPU下,可以使用4字节或者8字节的reference

所以无论如何,对reference的操作肯定是单步操作,是automic的。

事实上,一个蛮有用的例子是cache switch - 你有两个cache pool,分别用两个reference指向:cache_in_build和cache_in_use,等cache_in_build完成了,你需要把cache_in_use指向它,没有问题,这是线程安全的。

但是问题是,jvm可以会reorder你的statement:

  1. cache_in_build.build()
  2. cache_in_use = cache_in_build

期望是cache在build完了之后,切换过去。

但是这两行代码并没有前后的dependency关系,所以JVM可以为了优化,进行乱序执行,变成:

  1. cache_in_use = cache_in_build
  2. cache_in_build.build()

于是,如果另一个线程在使用cache_in_use,在代码#1执行完之后,就访问到了正在build的那个cache,这是个问题。

解决方案是cache_in_use必须定义为volatile,保证happen-before的关系,拒绝乱序执行,从而保证其他线程看到的数据是有效的。

Java中primitive type的线程安全性的更多相关文章

  1. 关于java中final关键字与线程安全性

    在Java5中,final关键字是非常重要而事实上却经常被忽视其作为同步的作用.本质上讲,final能够做出如下保证:当你创建一个对象时,使用final关键字能够使得另一个线程不会访问到处于" ...

  2. Java中的进程和线程

     Java中的进程与线程 一:进程与线程 概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是 ...

  3. Java中的进程与线程(总结篇)

    详细文档: Java中的进程与线程.rar 474KB 1/7/2017 6:21:15 PM 概述: 几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进 ...

  4. JAVA 中无锁的线程安全整数 AtomicInteger介绍和使用

    Java 中无锁的线程安全整数 AtomicInteger,一个提供原子操作的Integer的类.在Java语言中,++i和i++操作并不是线程安全的,在使用的时候, 不可避免的会用到synchron ...

  5. java中的++i是线程安全的吗?

    java中的++i是线程安全的吗?为什么?怎么使它线程安全呢? 先说答案: 非线程安全 先说下为什么是非线程安全的? 从Java内存模型说起 Java内存模型规定了所有的便利都存储在主内存中,每个线程 ...

  6. (转)java中的进程与线程

    (转自地址http://www.ibm.com/developerworks/cn/java/j-lo-processthread/) Java 进程的建立方法 在 JDK 中,与进程有直接关系的类为 ...

  7. 在JAVA中ArrayList如何保证线程安全

    [b]保证线程安全的三种方法:[/b]不要跨线程访问共享变量使共享变量是final类型的将共享变量的操作加上同步一开始就将类设计成线程安全的, 比在后期重新修复它,更容易.编写多线程程序, 首先保证它 ...

  8. Java并发编程实战 之 线程安全性

    1.什么是线程安全性 当多个线程访问某个类时,不管运行时环境采用何种调用方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全 ...

  9. java中那些类是线程安全的?

    Java中各种集合(字符串类)的线程安全性!!! 一.概念: 线程安全:就是当多线程访问时,采用了加锁的机制:即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读 ...

随机推荐

  1. mysql 命令行操作入门(详细讲解版)

    之前分享过多次Mysql主题,今天继续分享mysql命令行入门   1. 那么多mysql客户端工具,为何要分享命令行操作? -快捷.简单.方便 -在没有客户端的情况下怎么办 -如果是mysql未开启 ...

  2. Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作

    2 Mongodb CRUD 操作 Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作Mongodb Manual阅读笔记:CH3 数据模型(Data Models)Mong ...

  3. Consul 启动命令

    服务端: nohup consul agent -server -bootstrap-expect 1 -config-dir /etc/consul.d/ -data-dir /var/opt/co ...

  4. Java api 入门教程 之 JAVA的IO处理

    IO是输入和输出的简称,在实际的使用时,输入和输出是有方向的.就像现实中两个人之间借钱一样,例如A借钱给B,相对于A来说是借出,而相对于B来说则是借入.所以在程序中提到输入和输出时,也需要区分清楚是相 ...

  5. su认证失败&文件夹里打开终端的方法&atom安装

    很久没用笔记本上的ubuntu,用不顺手,比在公司调教了半年多的电脑差远了.一步一步来.先解决最不顺手的三件事 1.su认证失败. 新安装的ubuntu系统是无法切换到root账户的,得做一番修改 s ...

  6. HTML属性的长度问题

    越来越多的同学喜欢把数据存放在html属性上,比如 <p data-info="{a:1,b:2}">xxx</p> 一堆JSON数据放在data-info ...

  7. 一个PHP混淆后门的分析

    洒家的朋友的公司的某个站发现最近被上传了一个后门程序.为了取证我们抓取了HTTP请求流量,看到了一堆莫名其妙看似经过混淆的请求,响应也是看似base64的乱码.洒家用了2个小时静态分析了一遍,并写了利 ...

  8. stm32 中断几个库函数实现过程分析

    感谢原文作者:鱼竿的传说,这篇文章写得不错,转载自 http://www.cnblogs.com/chineseboy/archive/2013/03/14/2956782.html 前题: 闭门造车 ...

  9. nodejs入门

    一.Nodejs介绍 简单的说 Node.js 就是运行在服务端的 JavaScript的代码解析器. 首先要清楚Node不是一个Web服务器,这十分重要.它本身并不能做任何事情.它无法像Apache ...

  10. Objective-C基础数据类型-NSSet[转]

    转自GISerYang 集合: 集合(NSSet)和数组(NSArray)有相似之处,都是存储不同的对象的地址:不过NSArray是有序的集合,NSSet是无序的集合. 集合是一种哈希表,运用散列算法 ...