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. Play Framework 完整实现一个APP(一)

    A blog engine project yabe. 1.创建工程 >play new yabe 设置Application Name: Yet Another Blog Engine. 2. ...

  2. sqlserver删除所有表(表结构和数据)

    要删除某个数据库,或者删除数据库中的所有表(删除表结构和数据),需要先删除表间的外键约束,才能删除表.如删除数据库db_wy中的所有表: --/第1步**********删除所有表的外键约束***** ...

  3. MS SQL Server2014链接MS SQL Server 2000

    开发与企业应用中,好几个版本SQL Server相互链接.分布式读取与存储,需要实现sp_addlinkedserver.SQL Server 2000, SQL Server 2008, SQL S ...

  4. java web 开发 购物车功能的实现

    为了方便自己以后复习,所以写的比较仔细,记录下自己的成长..... 既然是做购物车,那么前提条件是首先需要一系列商品,也就是要建一个实体,这里建了一个商品表. 通过查询在浏览器上显示 基本显示已经做好 ...

  5. 尝试一下sql server2016里面的json功能

    前2天下载了一个2016的rc版本来玩一下,首先感觉是~开发者版本免费啦!!撒花!!!另外一个东西,sql server 2016能支持json 的解析和应用啦,虽然我不知道它的性能如何,先来一发测试 ...

  6. Servlet/JSP-07 Session应用

    Session应用 一. 避免表单重复提交 1. 表单重复提交的情况 ①在表单提交到一个 Servlet,而 Servlet 又通过请求转发的方式响应了一个 JSP 或者 HTML 页面,此时浏览器地 ...

  7. iOS 内存错误调试(EXC_BAD_ACCESS)

    内存错误crash现场: Thread堆栈: 有可能是访问被释放对象造成,根据现场并不能找到具体哪个对象出现内存错误. 1.开启僵尸对象调试 Edit Scheme->Debug->Dia ...

  8. js判断手机访问PC端跳转到手机站

    <script type="text/javascript">(function() { //得到域名后缀 var path = location.pathname.s ...

  9. 解决docker容器中文乱码,修改docker容器编码格式

    前台上传文件到服务器后,服务器返回给前台的文件列表中出现中文乱码,所有的中文文件名全部变成?,英文文件名则正常显示. 问题经过定位,发现后台代码的multipartfile类在执行transterto ...

  10. openfire+asmack搭建的安卓即时通讯(七) 15.5.27

    本地化之章! 往期传送门: 1.http://www.cnblogs.com/lfk-dsk/p/4398943.html 2.http://www.cnblogs.com/lfk-dsk/p/441 ...