volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性,即多线程环境中,使用 volatile 关键字的变量仅可以保证不同线程读取变量时,可以读到最新修改的变量值,但是修改变量值时,却不能保证线程安全(可能存在写值覆盖现象)。以下测试代码,展示了使用volatile关键字的几种方式。

 /**
* <b>volatile 关键字正确用法</b><br>
* @author Gaylen
* @version V1.1.0
* history
* 1.1.0, 2014年11月20日 Gaylen FE
* @since Java 6.0
*/
public class TestVolatile { /** volatile + atomic 保证读写安全 */
public static volatile AtomicInteger count1 = new AtomicInteger(0); /** volatile 实现读安全,但不能保证写安全 */
public static volatile int count2 = 0; /** volatile + synchronized 实现读写安全 */
public static volatile int count3 = 0; /** static 仅保证全局唯一,但不能保证读写安全 */
public static int count4 = 0; public static synchronized void count3Increment() {
TestVolatile.count3++;
} /** 测试线程数 */
public static final int numOfThread = 1000; /** 线程辅助类,保证所有线程执行完毕 */
private static CountDownLatch countDownLatch = new CountDownLatch(numOfThread); public static void increment() {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
count1.getAndIncrement();
count2++;
count3Increment();
count4++;
} /**
* 输出结果
* 等待所有线程执行完毕后,输出结果
*/
public static void print() {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("运行结果: count1=" + TestVolatile.count1.get());
System.out.println("运行结果: count2=" + TestVolatile.count2);
System.out.println("运行结果: count3=" + TestVolatile.count3);
System.out.println("运行结果: count4=" + TestVolatile.count4);
System.out.println("---------------------------------------"); } /**
* <b>程序入口</b><br>
* 同时启动1000个线程,进行增加操作
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < numOfThread; i++) {
new Thread(new Runnable() { @Override
public void run() {
for (int index = 0; index < 1000; index++) {
TestVolatile.increment();
}
countDownLatch.countDown();
}
}).start();
}
print();
}
}

测试程序输出结果如下:

运行结果: count1=1000000
运行结果: count2=998528
运行结果: count3=1000000
运行结果: count4=999892
---------------------------------------

通过测试程序可知,使用 volatile + synchronized 方式 或者 volatile + 原子变量 方式可以同时保证多线程环境下安全的变量读写。

[Java多线程] volatile 关键字正确使用方法的更多相关文章

  1. Java 多线程 - Volatile关键字

    作者: dreamcatcher-cx 出处: <http://www.cnblogs.com/chengxiao/> 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明 ...

  2. java多线程 -- volatile 关键字 内存 可见性

    内存可见性(Memory Visibility) 1 内存可见性(Memory Visibility)是指当某个线程正在使用对象状态而另一个线程在同时修改该状态,需要确保当一个线程修改了对象状态后,其 ...

  3. Java多线程——volatile关键字、发布和逸出

    1.volatile关键字 Java语言提供了一种稍弱的同步机制,即volatile变量.被volatile关键字修饰的变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在每次读取volatit ...

  4. Java多线程-----volatile关键字详解

       volatile原理     Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程.当把变量声明为volatile类型后, 编译器与运行时都会注意 ...

  5. JAVA多线程---volatile关键字

    加锁机制既可以确保可见性又可以保证原子性,而volatile变量只能确保可见性. 当把变量声明为volatile时候 编译器与运行时都会注意到这个变量是共享的,不会将该变量上的操作与其他内存操作一起重 ...

  6. 【转】java中volatile关键字的含义

    java中volatile关键字的含义   在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...

  7. 转:java中volatile关键字的含义

    转:java中volatile关键字的含义 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...

  8. Java中Volatile关键字详解 (转自郑州的文武)

    java中volatile关键字的含义:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 一.基本概念 先补充一下概念:J ...

  9. Java 多线程 —— synchronized关键字

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

随机推荐

  1. Perl语言入门--2--perl的运算符

    一.算数运算符 **:是幂 结果不能超过数的范围 当指数为小数时 底数不能为负数 %:取余数  两边的操作数为整数,如果不是则要截取,把所有的小数部分去掉 注意:当一个字符串参加运算,需要转化为整数时 ...

  2. yii批量插入数据

    现在有如下数据: 查看代码   打印 1 $user=array( 2     0=>array('id'=>1,'name'=>'张三'), 3     0=>array(' ...

  3. AC日记——Andryusha and Socks Codeforces 780a

    A. Andryusha and Socks time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  4. SQL Server 内置函数实现MD5加密

    一.MD5加密 HASHBYTES ('加密方式', '待加密的值')     加密方式= MD2 | MD4 | MD5 | SHA | SHA1     返回值类型:varbinary(maxim ...

  5. 洛谷—— P2117 小Z的矩阵

    https://www.luogu.org/problemnew/show/2117 题目描述 小Z最近迷上了矩阵,他定义了一个对于一种特殊矩阵的特征函数G.对于N*N的矩阵A,A的所有元素均为0或1 ...

  6. tr命令用法

    原文链接 # echo "abcd"|tr 'a' 'b' bbcd tr 命令 用途 转换字符. 语法 tr [ -c | -cds | -cs | -C | -Cds | -C ...

  7. Java中泛型T和Class<T>以及Class<?>的理解(转)

    注意:class是java的关键字, 在声明Java类时使用; Class类的实例表示Java应用运行时的类(class ans enum)或接口(interface and annotation)( ...

  8. 配置laravel的nginx站点

    server{}配置 server{ #端口配置 listen 80; #域名配置 server_name laravel.cc; index index.php index.html index.h ...

  9. [Bash] Understand and Use Functions in Bash

    n this lesson, we'll go over how bash functions work. Bash functions work like mini bash scripts--yo ...

  10. 谈谈Runtime类中的freeMemory,totalMemory,maxMemory几个方法

    最近在网上看到一些人讨论到java.lang.Runtime类中的freeMemory(),totalMemory(),maxMemory ()这几个方法的一些问题,很多人感到很疑惑,为什么,在jav ...