【java多线程】多线程中的long和double
在看一些代码的时候,会发现在定义long型和double型的变量时,会在前面加上volatile关键字,当然也会看到在其它原子类型的变量前加上这个关键字,但这里要说的还是有区别的。
在java中,java的内存模型要求,变量的读取操作和写入操作都必须是原子操作的,但是对于非volatile类型的long和double有些不同,因为这两个变量是64位存储,JVM允许将64位的读操作或写操作分解为2个32位的操作。这样,当在多线程环境中读取一个非volatile的long变量时,可能会出现读取到这个变量一个值的高32位和另一个值的低32位,从而导致数据出问题。
这里还需要说明下volatile关键字的作用,可以说有2个作用,其一是,用volatile修饰的变量的读取和写入都是直接操作内存,以保证被其它线程读取到值都是最新的,或者称之为确保内存的可见性;其二是,保证变量的读取和写入操作都是原子操作,就是上面long和double的读取所遇到的问题,注意这里提到的原子性只是针对变量的读取和写入,并不包括对变量的复杂操作,比如i++就无法使用volatile来确保这个操作是原子操作。
所以,在多线程环境中,要确保long和double变量的数据正确,可以使用volatile关键字修饰变量,也可以采用同步机制来保证数据的正确性。
另外《java并发编程实战》中也讲到了使用volatile的需要满足的所有条件:
a、对变量的写入操作不依赖于变量当前的值,或者你能确保只有单个线程更新变量的值
b、该变量不会与其他状态变量一起纳入不变性条件中
c、在访问变量时不需要加锁
参看《java并发编程实战》第三章
对于 i++这种为什么不能使用volatile解决,可以参考:
http://www.cnblogs.com/wentaos/p/7407089.html
【java多线程】多线程中的long和double的更多相关文章
- JAVA并发七(多线程环境中安全使用集合API)
在集合API中,最初设计的Vector和Hashtable是多线程安全的.例如:对于Vector来说,用来添加和删除元素的方法是同步的.如果只有一个线程与Vector的实例交互,那么,要求获取和释放对 ...
- Java多线程编程中Future模式的详解
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
- 转:【Java并发编程】之八:多线程环境中安全使用集合API(含代码)
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17200509 在集合API中,最初设计的Vector和Hashtable是多线程安 ...
- Java多线程编程中Future模式的详解<转>
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
- 【Java并发编程】:多线程环境中安全使用集合API
在集合API中,最初设计的Vector和Hashtable是多线程安全的.例如:对于Vector来说,用来添加和删除元素的方法是同步的.如果只有一个线程与Vector的实例交互,那么,要求获取和释放对 ...
- 【Java并发编程】之八:多线程环境中安全使用集合API
在集合API中,最初设计的Vector和Hashtable是多线程安全的.例如:对于Vector来说,用来添加和删除元素的方法是同步的.如果只有一个线程与Vector的实例交互,那么,要求获取和释放对 ...
- Java多线程编程(2)--多线程编程中的挑战
一.串行.并发和并行 为了更清楚地解释这三个概念,我们来举一个例子.假设我们有A.B.C三项工作要做,那么我们有以下三种方式来完成这些工作: 第一种方式,先开始做工作A,完成之后再开始做工作B ...
- java之多线程 二
线程的生命周期: 当线程被创建并被启动时,它既不是一启动就进入了执行状态,在线程的生命周期中,它要经过new(新建),就绪(Runnable),运行(Running),阻塞(Blocked),dead ...
- zz剖析为什么在多核多线程程序中要慎用volatile关键字?
[摘要]编译器保证volatile自己的读写有序,但由于optimization和多线程可以和非volatile读写interleave,也就是不原子,也就是没有用.C++11 supposed会支持 ...
随机推荐
- OO方式实现ALV: cl_salv_table
这里总结最近用cl_salv_table实现ALV遇到问题和解决办法 FORM set_alv2 . DATA: lv_syrepid TYPE syrepid. lv_syrepid = sy-cp ...
- kbmMW均衡负载与容灾(1)
kbmMW为均衡负载与容灾提供了很好的机制,支持多种实现方式,现在看看最简单的一种,客户端控制的容灾和简单的负载均衡. 现在,我们将kbmMWServer部署到不同的服务器,或者在同一服务器部署多份实 ...
- Redis日志级别
Redis默认的设置为verbose,开发测试阶段可以用debug,生产模式一般选用notice 1. debug:会打印出很多信息,适用于开发和测试阶段 2. verbose(冗长的):包含很多不太 ...
- 3.Shell 接收用户的参数
1.Shell 传递参数 我们可以在执行 Shell 脚本时,向脚本传递参数,Linux系统中的Shell脚本语言已经内设了用于接收参数的变量,变量之间可以使用空格间隔. 例如$0对应的是当前Shel ...
- Linux之top 监视系统任务的工具
top 监视系统任务的工具: 和ps 相比,top是动态监视系统任务的工具,top 输出的结果是连续的: top 命令用法及参数: top 调用方法: top 选择参数 参数: -b 以批量模式运 ...
- C#:调用存储过程方法
MySqlParameter p1 = new MySqlParameter("id", MySqlDbType.Int32); p1.Value = sid; MySqlPara ...
- JS 函数相关的声明调用
// 函数声明方法一 function f (a, b) { return a + b; } // 函数调用 console.log(f(1, 4)); // 函数声明方法二 var num = fu ...
- linux内核 内存管理
以下内容汇总自网络. 在早期的计算机中,程序是直接运行在物理内存上的.换句话说,就是程序在运行的过程中访问的都是物理地址. 如果这个系统只运行一个程序,那么只要这个程序所需的内存不要超过该机器的物理内 ...
- 对bloom的理解 及优化
varying uv放到vs 讲下bloom的细节 上图这种做法 temporally stable box filtering up 的时候 需要filter 上述upscale有两张srv dow ...
- HDU 6044 - Limited Permutation | 2017 Multi-University Training Contest 1
研究一下建树 : /* HDU 6044 - Limited Permutation [ 读入优化,笛卡尔树 ] | 2017 Multi-University Training Contest 1 ...