网上关于java volatile的资料已经不少了,但搜了好久也没看到谁用代码很好地验证过使不使用volatile的差异。最近自己写了个测试,意外的看到了两者的明显区别,为什么说意外呢,因为根据我的测试,在32位的JVM(以下均指oracle官方的JVM)上是看不出差异的,也就是说32位的JVM上,不会发生因为没使用volatile而引起的多个线程读写公共变量不同步问题(有误,见末尾的补充),偶然在64位的JVM上跑了下,问题一下出现了。我一直是用32位的JVM做测试,一直把问题的不出现归结于概率太低,所以没遇到,以致于我写了下面这个把这个小概率事件成倍放大的测试,但还是没看出差异,后来放到64位的JVM上,问题一下就出现了,程序直接不退出了

/**
* volatile关键字的测试
* @author trytocatch
* @date 2013-1-7
*/
public class Volatile {
long time1;//test运行时,使用两独立的变量来保存时间,避免因使用同步而对t1,t2造成影响
long time2;
volatile boolean boolValue=true;//volatile
public static void main(String[] args) throws InterruptedException{
int size=5000;//测试个数
Volatile vs[]=new Volatile[size];
long timeSum = 0;
for(int n=0;n<size;n++)
(vs[n]=new Volatile()).test();
// Thread.sleep(1000);
for(int n=0;n<size;n++){//统计出,所有线程从boolValue变为false到while(boolValue)跳出所花时间的总和
timeSum+=vs[n].time2 - vs[n].time1;
System.out.print(n+"\t"+vs[n].time2 +'\t' + vs[n].time1+'\t'+(vs[n].time2 - vs[n].time1)+'\n');
}
System.out.println("响应时间总和(毫微秒):"+timeSum);
long time1,time2;
time1 = System.nanoTime();
// Thread.yield();
time2 = System.nanoTime();
System.out.println(time2-time1);//顺序执行两条语句的时间间隔,供参考
} public void test() throws InterruptedException{
Thread t2=new Thread(){
public void run(){
while(boolValue)
;
time2 = System.nanoTime();
}
};
Thread t1=new Thread(){
public void run(){
time1 = System.nanoTime();
boolValue=false;
}
};
t2.start();
Thread.yield();
t1.start();
t1.join();//保证一次只运行一个测试,以此减少其它线程的调度对 t2对boolValue的响应时间 的影响
t2.join();
}
}

至于我上面说的,在32位JVM上,不会发生因为没使用volatile而引起的多个线程读写公共变量不同步问题,因为我把测试的size增加到50000也没出一个问题,而且一放到64位JVM上,问题立马出现,所以可以断定是JVM的差异,至于为什么32位的JVM不会出问题,难道是它根本没做优化?希望JVM高手指点


补充:今天在网上看到个资料,64位jvm只有server模式(server模式会进行更多的优化),32位JVM默认使用client模式,我将32位JVM设置为server模式后,问题同样出现了,平时不出现,是因为它根本就没做这方面的优化,所以,“在32位JVM上,不会发生因为没使用volatile而引起的多个线程读写公共变量不同步问题”的说法有误,只是参数不同而已

http://www.cnblogs.com/trytocatch/archive/2013/01/07/2850002.html

java volatile的一个验证反例(转)的更多相关文章

  1. Java并发编程之验证volatile不能保证原子性

    Java并发编程之验证volatile不能保证原子性 通过系列文章的学习,凯哥已经介绍了volatile的三大特性.1:保证可见性 2:不保证原子性 3:保证顺序.那么怎么来验证可见性呢?本文凯哥(凯 ...

  2. 一个具体的例子学习Java volatile关键字

    相信大多数Java程序员都学习过volatile这个关键字的用法.百度百科上对volatile的定义: volatile是一个类型修饰符(type specifier),被设计用来修饰被不同线程访问和 ...

  3. [Java并发编程(四)] Java volatile 的理论实践

    [Java并发编程(四)] Java volatile 的理论实践 摘要 Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 ...

  4. Java volatile关键字详解

    Java volatile关键字详解 volatile是java中的一个关键字,用于修饰变量.被此关键修饰的变量可以禁止对此变量操作的指令进行重排,还有保持内存的可见性. 简言之它的作用就是: 禁止指 ...

  5. java volatile进阶(一)

    本篇文章继续学习volatile.上篇文章简单的介绍了volatile和synchonized,这篇文章讲一下什么时候可以用volatile. 先看一段代码. package com.chzhao.v ...

  6. java volatile关键字的理解

    转载:http://shmilyaw-hotmail-com.iteye.com/blog/1672779 一个多线程的示例引发的问题 在讨论这个关键字之前先看一个多线程的示例代码: public c ...

  7. JAVA课程设计——一个简单的教务人事管理系统

    大三上学期期末总结,没错,上学期,写在下学期新学期开始,哈哈哈. 上学期学习了面向对象程序设计,课程设计的题目使用JAVA语言完成一个简单的教务人事管理系统,能够实现访问数据库的登录验证,分别按部门和 ...

  8. [Java并发编程(五)] Java volatile 的实现原理

    [Java并发编程(五)] Java volatile 的实现原理 简介 在多线程并发编程中 synchronized 和 volatile 都扮演着重要的角色,volatile 是轻量级的 sync ...

  9. [Java并发编程(三)] Java volatile 关键字介绍

    [Java并发编程(三)] Java volatile 关键字介绍 摘要 Java volatile 关键字是用来标记 Java 变量,并表示变量 "存储于主内存中" .更准确的说 ...

随机推荐

  1. 【Win7】【磁盘管理】删除相似“33fbc1d57e9aaf1ea88e6f08”缓存目录

    一般,在计算机磁盘.移动硬盘.或U盘出现,类别似"33fbc1d57e9aaf1ea88e6f08",你不能删除缓存目录.能Win7删除. (1).使用管理员,打开命令提示符窗口( ...

  2. Eclipse工具的问题

    1 Eclipse采用ctrl抄 粘贴很卡 Eclipse -- Windows->Preferences->General->Editors->Text Editors-&g ...

  3. 2048 Puzzle游戏攻略

    2048 Puzzle这是目前手机游戏的很火. 在地铁上经常看到的人玩这个游戏. 首先,简介2048 Puzzle游戏. 游戏界面是4X4广场格,每一方格可以放置在数字. 有四种移动数字的方法,向左. ...

  4. Android异步任务

    本文主要探讨Android平台提供的各种异步载入机制,包括它们的适用场景.用法等. 1. AsynTask AsynTask适用于最长能够持续几秒钟的短时间的操作,对于长时间的操作,建议使用java. ...

  5. IIS7构造Gzip压缩

    IIS7构造Gzip压缩 本文来自Kevin Yang博客 作者:Kevin Yang 开启配置HTTP压缩(GZip) 在IIS7中配置Gzip压缩相比IIS6来说实在easy了很多.并且默认情况下 ...

  6. uboot的relocation原理具体分析

    近期在一直在做uboot的移植工作,uboot中有非常多值得学习的东西.之前总结过uboot的启动流程,但uboot一个非常核心的功能没有细致研究.就是uboot的relocation功能. 这几天研 ...

  7. [LeetCode258] Add Digits 非负整数各位相加

    题目: Given a non-negative integer num, repeatedly add all its digits until the result has only one di ...

  8. Lua中的weak表——weak table(转)

    弱表(weak table)是一个很有意思的东西,像C++/Java等语言是没有的.弱表的定义是:A weak table is a table whose elements are weak ref ...

  9. C# - is

     Checks if an object is compatible with a given type. An is expression evaluates to true if the pr ...

  10. C# WinForm 拖动无边框窗体 改变无边框窗体尺寸

    经常遇到这种情况.窗体的边框去掉了.然后种种问题就出来了:不能拖动.不能改变窗体大小.不能......当然.肯定有解决方案滴*^_^*今天的目标就是:可以直接拖动没有边框的窗体.可以直接拉拽窗体改变其 ...