网上关于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. Oracle SQL Lesson (10) - 使用DDL语句创建和管理表

    数据库对象TableViewSequenceIndexSynonym 对象名称最长30个字符,不能与当前用户下其他对象重名.create table "select" as sel ...

  2. 全文检索引擎Solr 指南

    全文检索引擎Solr系列:第一篇:http://t.cn/RP004gl.第二篇:http://t.cn/RPHDjk7 .第三篇:http://t.cn/RPuJt3T

  3. 《Java程序书面采访猿收藏》之 instanceof的作用是什么

    instanceof它是Java二元运算语言,它的作用是推断对象变量引用被指向的类型是一类(或接口.抽象类.父亲)示例.即,对象是否是它的一个实例离开它的类的权.返回boolean数据类型. 常见的使 ...

  4. js“分享到”侧边框伸缩实现

    思路: 1,临界值是 -150 和 0 如果大于临界值,就要隐藏 2,隐藏:速度为负 显示:速度为正 3,如果与临界值相等,就清空定时器 否则,就运动 ------------------------ ...

  5. How to install PL/SQL developer on linux (转)

    PL/SQL developer 在linux上的安装方法工欲善其事必先利其器,PL/SQL和toad对于ORACLE从业人员来说都是很重要的工具,但这些工具都没有linux的发行版,如果要在linu ...

  6. 同台交换机同样VLAN能够通信,不同VLAN不可通信

    一.示意图 二.IP规划 PC0:192.168.0.100  255.255.255.0        PC1:192.168.0.110  255.255.255.0        PC2:192 ...

  7. 大约C++ const 全面总结

    C++中的const关键字的使用方法很灵活,而使用const将大大改善程序的健壮性,本人依据各方面查到的资料进行总结例如以下,期望对朋友们有所帮助. Const 是C++中经常使用的类型修饰符,常类型 ...

  8. UVA - 12001 UVa Panel Discussion

    Description  UVa Panel Discussion  The UVa online judge team is arranging a panel discussion for the ...

  9. 系统如何端子app弄root才干

    最近由于调试USB OTG怪东西.这导致USB端口被占用,这项.虽然我是project版本号,但不能运行adb shell,这是不可能的debug该. 所以,我现在是一个系统终端apk,规划 http ...

  10. robot framework 使用三:他们主动浏览器的兼容性

    robot framework 浏览器兼容性测试 上图中黄色圈的地方默认什么都不写,是firefox浏览器.写上ie就是ie浏览器了 firefox最新版本号即可,ie须要设置: 1. IE选项设置的 ...