volatile关键字相信了解Java多线程的读者都很清楚它的作用。volatile关键字用于声明简单类型变量,如int、float、boolean等数据类型。如果这些简单数据类型声明为volatile,对它们的操作就会变成原子级别的。但这有一定的限制。例如,下面的例子中的n就不是原子级别的:


package mythread; public class JoinThread extends Thread {
public static volatile int n = 0; public void run() {
for (int i = 0; i < 10; i++) try { n = n + 1; sleep(3); // 为了使运行结果更随机,延迟3毫秒 } catch (Exception e) { } } public static void main(String[] args) throws Exception { Thread threads[] = new Thread[100]; for (int i = 0; i < threads.length; i++) // 建立100个线程 threads[i] = new JoinThread(); for (int i = 0; i < threads.length; i++) // 运行刚才建立的100个线程 threads[i].start(); for (int i = 0; i < threads.length; i++) // 100个线程都执行完后继续 threads[i].join(); System.out.println(“n=” + JoinThread.n); } }

如果对n的操作是原子级别的,最后输出的结果应该为n=1000,而在执行上面积代码时,很多时侯输出的n都小于1000,这说明n=n+1不是原子级别的操作。原因是声明为volatile的简单变量如果当前值由该变量以前的值相关,那么volatile关键字不起作用,也就是说如下的表达式都不是原子操作:

n = n + 1;

n++;

如果要想使这种情况变成原子操作,需要使用synchronized关键字,如上的代码可以改成如下的形式:


package mythread; public class JoinThread extends Thread { public static int n = 0; public static synchronized void inc() { n++; } public void run() { for (int i = 0; i < 10; i++) try {
inc(); // n = n + 1 改成了 inc(); sleep(3); // 为了使运行结果更随机,延迟3毫秒 } catch (Exception e) { } } public static void main(String[] args) throws Exception { Thread threads[] = new Thread[100]; for (int i = 0; i < threads.length; i++) // 建立100个线程 threads[i] = new JoinThread(); for (int i = 0; i < threads.length; i++) // 运行刚才建立的100个线程 threads[i].start(); for (int i = 0; i < threads.length; i++) // 100个线程都执行完后继续 threads[i].join(); System.out.println(“n=” + JoinThread.n); } }

上面的代码将n=n+1改成了inc(),其中inc方法使用了synchronized关键字进行方法同步。因此,在使用volatile关键字时要慎重,并不是只要简单类型变量使用volatile修饰,对这个变量的所有操作都是原来操作,当变量的值由自身的上一个决定时,如n=n+1、n++等,volatile关键字将失效,只有当变量的值和自身上一个值无关时对该变量的操作才是原子级别的,如n = m + 1,这个就是原级别的。所以在使用volatile关键时一定要谨慎,如果自己没有把握,可以使用synchronized来代替volatile。

慎重使用volatile关键字的更多相关文章

  1. Java多线程初学者指南(6):慎重使用volatile关键字

    volatile关键字相信了解Java多线程的读者都很清楚它的作用,和sychnorized 一样用于多线程的同步.volatile关键字用于声明简单类型变量,如int.float.boolean等数 ...

  2. java多线程-慎重使用volatile关键字

    Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了实现代码线程的安全性.其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低),而 ...

  3. java 轻量级同步volatile关键字简介与可见性有序性与synchronized区别 多线程中篇(十二)

    概念 JMM规范解决了线程安全的问题,主要三个方面:原子性.可见性.有序性,借助于synchronized关键字体现,可以有效地保障线程安全(前提是你正确运用) 之前说过,这三个特性并不一定需要全部同 ...

  4. java内存模型(线程,volatile关键字和sychronized关键字)

    volatile关键字 用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况. ...

  5. Java并发编程:volatile关键字解析

    Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...

  6. volatile关键字 学习记录2

    public class VolatileTest2 implements Runnable{ volatile int resource = 0; public static void main(S ...

  7. volatile关键字 学习记录1

    虽然已经工作了半年了...虽然一直是在做web开发....但是平时一直很少使用多线程..... 然后最近一直在看相关知识..所以就有了这篇文章 用例子来说明问题吧 public class Volat ...

  8. 【转】Java并发编程:volatile关键字解析

    转自:http://www.importnew.com/18126.html#comment-487304 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备 ...

  9. 架构师养成记--4.volatile关键字

    volatile修饰的变量可在多个线程间可见. 如下代码,在子线程运行期间主线程修改属性值并不对子线程产生影响,原因是子线程有自己独立的内存空间,其中有主内存中的变量副本. public class ...

随机推荐

  1. 个推应用统计产品(个数)Android集成实践

    前段时间,我们公司的产品又双叒叕给我们提了新需求,要求我们把APP相关的数据统计分析一下,这些指标包括但不限于应用每日的新增.活跃.留存率等等,最好每天都能提供数据报表.这种事情真是想想就麻烦,大家最 ...

  2. 对Property进行RACObserve

    @property (assign,nonatomic) int price; @property (assign,nonatomic) int time; [RACObserve(self,pric ...

  3. 一个ssm综合小案例-商品订单管理-第一天

    项目需求分析: 功能需求:登录,商品列表查询,修改 项目环境及技术栈: 项目构成及环境: 本项目采用 maven 构建 环境要求: IDEA Version: 2017.2.5 Tomcat Vers ...

  4. Rime中州韵导入QQ五笔词库

    过程记录如下: 1.在QQ五笔中导出QQ五笔系统词库 2.使用「深蓝词库转换」转换QQ五笔系统词库,输入源修改为”五笔86版“,输出方式修改为Rime中州韵-五笔. 3.在Ubuntu中打开Termi ...

  5. 如何新建Quartus工程—FPGA入门教程【钛白Logic】

    这一章我们来实现第一个FPGA工程—LED流水灯.我们将通过流水灯例程向大家介绍一次完整的FPGA开发流程,从新建工程,代码设计,综合实现,管脚约束,下载FPGA程序.掌握本章内容,大家就算正式的开始 ...

  6. AUI-靠谱的移动前端框架

    在如何开发出优秀的APICloud应用中ApiCloud官方推荐我们使用轻量级的框架AUI,针对AUI官网没有提供体验地址 特意编译了一个APP供给大家体验 aui官方地址:http://www.au ...

  7. React-Native 之 TabBarIOS

    前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...

  8. .gitkeep

    看一个开源项目中有个.gitkeep文件,不知道是干嘛用的查询知道 git是不允许提交一个空的目录到版本库上的,可以在空的文件夹里面建立一个.gitkeep文件,然后提交去即可. 其实在git中 .g ...

  9. Coursera台大机器学习技法课程笔记13-Deep Learning

    深度学习面临的问题和现在解决的办法: 简要来说,分两步使用DL:初始化时一层一层的选择权重,而后再进行训练: 那么怎么做pre-training,即怎么选择权重呢?好的权重能够不改变原有资料的信息,即 ...

  10. TPCC-MySQL安装、使用及结果解读

    tpcc-mysql用于MySQL基准测试,percona基于TPC-C(下面简写成TPCC)衍生出来的产品.下面对tpcc-mysql进行安装然后使用,最后结果解读,安装very easy,let ...