`

为什么Java中的long与double不是线程安全的?

 
阅读更多

 Long与double操作并不是原子的


java的部分执行 环境中,对于long以及double的操作并不是原子的。

        例如有一个long类型的longfield字段,某个线程正在执行:

        longfield = 123L ;

        这样的指定操作,而同时有另一个线程正在执行:

        longfield = 456L;

        这样的指定操作。之后longfield的值会是什么,是无法保证的。也许是123L,也可能是456L,或许是0L,甚至还可能是31415926L。

        所以我们可以的出下列结论:

        1.基本类型,引用类型的指定,引用是原子的操作;

        2.但是long与double的指定,引用是分割的;

        3.要在线程间共享long与double字段是,必须在synchronized中操作,或是声明为volatile。

 

以前只知道Java中的long与double不是线程安全的,但不知道为什么,读《深入java虚拟机》一书,了解了大概。
  Java虚拟机规范定义的许多规则中的一条:所有对基本类型的操作,除了某些对long类型和double类型的操作之外,都必须是原子级的。 
    由于规范没有规定如何实现,那么当今所知的虚拟机对这条规则的实现都是把32位值做为原子性对待,而不是64位做为原子性。那么,当线程把主存中的 long/double类型的值读到线程内存中时,可能是两次32位值的写操作,显而易见,如果几个线程同时操作,那么就可能会出现高低2个32位值出错 的情况发生,所以现在,java程序必须确保通过同步来操作共享的long和double。

 

参考: 1 《深入java虚拟机》

          2  Long与double操作并不是原子的 http://blog.csdn.net/xingqisan/archive/2009/02/25/3935169.aspx

          3  为什么Java中的long与double不是线程安全的? http://magnetocn.bokee.com/viewdiary.10946639.html

分享到:
评论

相关推荐

    Java面试问题带答案40道.docx

    答:Java中有八种基本数据类型,分别为byte、short、int、long、float、double、char和boolean。 2. Java中如何实现多线程? 答:可以通过继承Thread类或实现Runnable接口来创建线程。另外,还可以使用Executor框架...

    Java测试题2答案

    定义一个类名为"MyClass.java"的类,并且该类可被一个工程中的所有类访问,那么该类的正确声明应为:CD A double a=1.0; A private class MyClass extends Object B class MyClass extends Object C ...

    java八股文.docx "Java八股文"通常指的是一种简单的模板化回答,用于解答关于Java编程语言的基础问题,特别是在面试

    Java的基本数据类型包括整型(byte、short、int、long)、浮点型(float、double)、字符型(char)和布尔型(boolean)。 3. **Java中的访问修饰符有哪些?** Java中的访问修饰符包括public、protected、...

    JAVA面试题最全集

    一个“.java”原文件中是否可以包括多个类(不是内部类)? 53.掌握内部类和接口的概念 54.StringTokenizer类的使用 55.数据结构,如何遍历List中的元素? 如果要按照键值保存或者访问数据,使用什么数据结构? ...

    java笔试题大汇总

    Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。 原始类型封装类 booleanBoolean charCharacter byteByte shortShort intInteger longLong floatFloat doubleDouble ...

    Java企业面试问题2.txt

    2.1java中的8种基本数据类型:boolean byte char short int float double long 2.2:基本数据类型和它对应的封装类型之间可以相互转换,从基本数据类型到封装类 型叫做装箱,从封装类型到基本数据类型叫拆箱,...

    java 面试题 总结

    为什么要有GC?  GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域...

    天猫内部资料-Java并发编程

    对象类型: 对象地址原子读写,线程安全 并发读不可变状态,线程安全 并发读写可变状态,非线程线程 基本类型: int,char数值读写,线程安全 long,double高低位,非线程安全 i++等组合操作,非线程安全

    超级有影响力霸气的Java面试题大全文档

    为什么要有GC?  GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域...

    java面试题

    答:Servlet与CGI的区别在于Servlet处于服务器进程中,它通过多线程方式允许其service方法,一个实例可以服务于多个请求,并且其实例一般不会被销毁,而CGI对每个请求都产生新的进程,服务完后就销毁,所以效率上...

    深入Java虚拟机(原书第2版).pdf【附光盘内容】

    1.1 为什么使用java 1.2 网络带来的挑战和机遇 1.3 体系结构 1.3.1 java虚拟机 1.3.2 类装载器的体系结构 1.3.3 java class文件 1.3.4 java api 1.3.5 java程序设计语言 1.4 java体系结构的...

    java开发面试题及答案

    为什么? 答:有问题,因为3.4 是双精度数,将双精度型(double)赋值给浮点型(float)属于向下转型,可能会造成精度损失,所以必须进行强制类型转换,正确的写法是float number =(float)3.4;/ float number =3.4F;...

    深入理解_Java_虚拟机 JVM_高级特性与最佳实践

    / 342 13.1 概述 / 342 13.2 线程安全 / 343 13.2.1 Java语言中的线程安全 / 343 13.2.2 线程安全的实现方法 / 348 13.3 锁优化 / 356 13.3.1 自旋锁与自适应自旋 / 356 13.3.2 锁消除 / 357 13.3.3 锁粗化 ...

    java核心基础汇总.docx

    线程:Java中的线程是一种轻量级的执行单元,可以并发执行多个任务,提高程序的效率。 输入输出:Java中的输入输出主要包括标准输入输出流和文件操作等,可以读取用户输入和写入程序输出。 集合框架:Java中的集合...

    java基础入门教程

    4 软 件 最 终 产 品 :用 Java 语 言 开 发 的 软 件 可 以 具 有 可视化 、 可 听 化 、 可 操作 化 的 效 果 ,这 要 比 电 视 、 电 影 的 效果 更 为 理 想 ,因 为 它 可 以做 到 "即 时 、 交 互、 动 画 与 ...

    java面试800题

    volatile:volatile变量表示保证它必须是与主内存保持一致,它实际是""变量的同步"", 也就是说对于volatile变量的操作是原子型的,如用在long 或 double变量前,一般用于多线程编程。 abstract:抽象,必须重载,修饰...

    java面试笔试题大汇总

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。

    java在cpu的占有率

    private long javacount; /** 可使用内存. */ private long totalMemory; /** 剩余内存. */ private long freeMemory; /** 最大可使用内存. */ private long maxMemory; /** 操作系统. */ private ...

    Java笔试题目汇总

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。

Global site tag (gtag.js) - Google Analytics