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

public volatile boolean exit = false;
在定义exit时,使用了一个Java关键字volatile,这个关键字的目的是使exit同步,也就是说在同一时刻只能由一个线程来修改exit的值.

volatile关键字用于声明简单类型变量,如int、float、boolean等数据类型。如果这些简单数据类型声明为volatile,对它们的操作就会变成原子级别的。但这有一定的限制。例如,下面的例子中的n就不是原子级别的:

package junit.test;public class ThreadVolatile 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 ThreadVolatile();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=" + ThreadVolatile.n);}
}

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

package junit.test;public class ThreadVolatile2 extends Thread {public static volatile 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 ThreadVolatile2();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=" + ThreadVolatile2.n);}
}

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

本文转自http://www.cnblogs.com/linjiqin/p/3212737.html 感谢原作者

转载于:https://www.cnblogs.com/panxuejun/p/5957081.html

java多线程-慎重使用volatile关键字相关推荐

  1. Java 多线程 —— 深入理解 volatile 的原理以及应用

    转载自  Java 多线程 -- 深入理解 volatile 的原理以及应用 推荐阅读:<java 多线程-线程怎么来的> 这一篇主要讲解一下volatile的原理以及应用,想必看完这一篇 ...

  2. Java并发编程:volatile关键字解析(转载)

    转自https://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 Java并发编程:volatile关键字解析 v ...

  3. java中volatile_java中volatile关键字的含义

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

  4. 【Java并发编程:volatile关键字之解析】

    Java并发编程:volatile关键字解析 - Matrix海子 - 博客园 在Java 5之前,volatile是一个备受争议的关键字:因为在程序中使用它往往会导致出人意料的结果.在Java 5之 ...

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

    看到一篇写的很细致的文章,感谢作者 作者:Matrix海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者Matrix海子和博客园共有,欢 ...

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

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

  7. Java实战应用50篇(一)-Java并发编程:volatile关键字解析

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

  8. 慎重使用volatile关键字

    volatile关键字相信了解Java多线程的读者都很清楚它的作用.volatile关键字用于声明简单类型变量,如int.float.boolean等数据类型.如果这些简单数据类型声明为volatil ...

  9. java:彻底搞懂volatile关键字

    对于volatile这个关键字,相信很多朋友都听说过,甚至使用过,这个关键字虽然字面上理解起来比较简单,但是要用好起来却不是一件容易的事. 这篇文章将从多个方面来讲解volatile,让你对它更加理解 ...

  10. Java多线程:synchronized | Volatile 和Lock和ReadWriteLock多方位剖析(一)

    前言 本文站在多线程初中级学习者的角度,较为全面系统的带你一起了解多线程与锁相关的知识点.带你一起解开与锁相关的各种概念.用法.利弊等.比如:synchronized.Volatile.Lock.Re ...

最新文章

  1. ansys添加力矩_ansys中的workbench怎么添加力矩
  2. 纯CSS实现文字一行居中,多行左对齐的方法
  3. Redis Master/Slave 实践
  4. 字符函数和内存函数模拟实现
  5. HDU-1016 Prime Ring Problem DFS
  6. nginx 带宽_Nginx的Gzip功能
  7. wxml 判断 小程序_如何判断小程序外包公司是否靠谱
  8. iOS开发:icon和启动图尺寸(转)
  9. udp数据包大小问题
  10. PPT画得图转为矢量图eps
  11. contextcapture多区块点云_Smart 3D (ContextCapture) 4.4.6版本最新功能
  12. matlab的菜单编程实例,MATLAB-GUI 里面包含9个小例子,简单的讲述了各种控件和菜单menu的应用方法 ComboBox 组合框 266万源代码下载- www.pudn.com...
  13. 工程伦理(2021春)第四章课后习题答案
  14. 【Linux服务器】登录Linux服务器后,登陆信息显示佛祖保佑、永不死机,小猪佩奇等图案
  15. 虚拟化基本知识及virtio-net初探
  16. 对回合制游戏的探讨以及想法
  17. python如何画3个相切的圆_使用python绘制4个相切的圆形
  18. MySQL8.0Clone插件
  19. Informatica 中文字符
  20. python 使用selenium 批量获取url的cookies

热门文章

  1. php composer 框架,用 Composer 组建了个 PHP 框架
  2. ssl证书 所属项目怎么上传_Typora + 七牛云图床快速配置,告别手动上传图片!...
  3. 操作系统在内存中的位置
  4. c语言格式化浮点数多余的0
  5. 第 1 篇 Scrum 冲刺博客
  6. 48条高效率的PHP优化写法
  7. Spring Cloud Spring Boot mybatis 企业分布式微服务云(五)服务消费(Feign)【Dalston版】...
  8. 2016 Multi-University Training Contest 10
  9. RMAN-06217: 错误
  10. HOOK使用:全局键盘钩子