为什么80%的码农都做不了架构师?>>>

Java语言支持多线程,为了解决线程并发的问题,在语言内部引入了同步块synchronized和volatile关键字机制。在java线程并发处理中,关键字volatile比较少用,原因是:一、JDK1.5之前该关键字在不同的操作系统上有不同的表现,所带来是问题就是移植性差,二、是设计困难,而且误用较多。

‍‍synchronized ‍‍
    同步块,通过 synchronized 关键字来实现,所有加上synchronized 和块语句,在多线程访问的时候,同一时刻只能有一个线程能够用synchronized修饰的方法 或者 代码块。

volatile
    用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最新的值。volatile很容易被误用,用来进行原子性操作,它不能保证多个线程修改的安全性。

下我使用一个例子来说明这个特性。

不使用volatile:

public class NovolatileCounter {public static  int count = 0;/*** 自增运算,每次自增1*/public static void increase() {//这里延迟1毫秒,使得结果明显try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}count++;}public static void main(String[] args) {// 启动1000个线程,去进行自增运算for (int i = 0; i < 1000; i++) {new Thread(new Runnable() {@Overridepublic void run() {NovolatileCounter.increase();}}).start();}//这里每次运行的值都有可能不同,可能为1000System.out.println("Result: NovolatileCounter.count=" + NovolatileCounter.count);}
}

结果:

使用volatile:

public class VolatileCounter {public static volatile int count = 0;/*** 自增运算,每次自增1*/public static void increase() {//这里延迟1毫秒,使得结果明显try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}count++;}public static void main(String[] args) {// 启动1000个线程,去进行自增运算for (int i = 0; i < 1000; i++) {new Thread(new Runnable() {@Overridepublic void run() {VolatileCounter.increase();}}).start();}//这里每次运行的值都有可能不同,可能为1000System.out.println("Result: VolatileCounter.count=" + VolatileCounter.count);}
}

结果:


运行结果依然不是期望的1000,下面分析一下原因

从上图可以看到,对于一般变量的访问,线程在初始化时从主内存中加载所需要的变量值到工作内存中,然后在线程运行时,如果读取,则直接从工作内存中读取,若上写入则先写入到工作内存中,之后在刷新到主内存中,但是这样的结构在多线程的情况下可能会出现问题。如果A线程修改了变量的值,也刷新到主内存中去,但是B,C线程在此时间内读取的还是本线程的工作内存,也就是说读取的不是最新鲜的值,此时就出现了不同线程持有公共资源不同步的情况,可以使用synchronized同步代码块,也可以使用Lock锁来解决。

Java可以使用volatile关键字,确保每个线程对本地变量的访问和修改都直接与主内存交互,而不是与本地线程的工作内存交互的,保证每个线程都能获得最新的值。volatile变量的只剩如下图所示。

由上图可以看出,volatile变量的读写是分开进行的,如一个线程A读取了一个volatile变量,并且修改了这个变量,在修改的值写回主内存前,另一个线程B也读取了volatile变量,则B线程读取到的是原来的值,会造成数据的不一致。由此可以说明,volatile变量关键字并不能保证线程安全,它只能保证当线程需要该变量的值时,能够获得最近被修改的值,而不能保证多个线程的安全性。

转载于:https://my.oschina.net/shiinnny/blog/387263

【003】【深入解析Java中volatile关键字的作用】相关推荐

  1. java volatile有什么用_深入解析Java中volatile关键字的作用

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

  2. [转载] 浅析Java中volatile关键字及其作用

    参考链接: Java中的volatile关键字 在 Java 多线程中如何保证线程的安全性?那我们可以使用 Synchronized 同步锁来给需要多个线程访问的代码块加锁以保证线程安全性.使用 sy ...

  3. java关键字 valotile_Java内存模型-jsr133规范介绍,java中volatile关键字的含义

    最近在看<深入理解Java虚拟机:JVM高级特性与最佳实践>讲到了线程相关的细节知识,里面讲述了关于java内存模型,也就是jsr 133定义的规范. 系统的看了jsr 133规范的前面几 ...

  4. 【Java_基础】Java中Native关键字的作用

    本篇博文转载与:Java中Native关键字的作用 转载于:https://www.cnblogs.com/leiblog/p/10529056.html

  5. Java中super关键字及其作用

    Java中super关键字及其作用 super关键字及其作用 A:super关键字指代父类对象引用(super代表父类存储空间的标识) B:作用: a:访问被子类隐藏的父类同名成员变量和成员方法 : ...

  6. java 单独用this_以下不是Java中this关键字的作用的是()。

    [单选题]竖向荷载作用下剪力墙内力的计算,不考虑结构的连续性,可近似认为各片剪力墙只承受 [ ] [填空题(客观)]打开"开始"菜单的快捷键是 . [单选题]重载的方法需要通过形式 ...

  7. 认识Java中volatile关键字

    概念 1.可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情.为了确保多个线程之间对内 ...

  8. java中volatile关键字---学习笔记

    volatile关键字的作用 在java内存模型中,线程之间共享堆内存(对应主内存),但又各自拥有自己的本地内存--栈内存,线程的栈内存中缓存有共享变量的副本,但如果是被volatile修饰的变量,线 ...

  9. 就是要你懂 Java 中 volatile 关键字实现原理

    前言 我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是java.util.concurrent包的核心,没有volatile就没有这么多的并发类给我们使用. 本文详细解读一下v ...

最新文章

  1. Bootstrap-table学习笔记(一)
  2. 【数理知识】《积分变换与场论》王振老师-目录
  3. SAP Spartacus list item点击之后的detail页面跳转
  4. 传128GB版iPad4售价为799/929美元
  5. vuex构建vue项目_如何使用Vue.js,Vuex,Vuetify和Firebase构建单页应用程序
  6. 体重测试java算法代码_标准体重计算示例代码
  7. 利用Pelican搭建个人博客
  8. 省选知识清单/计划列表(咕?)
  9. oracle 仲宏伟,Oracle数据库的一些操作
  10. 数据结构试卷错题详细分析
  11. 【从零开始学习SLAM】ros navigation AMCL move_base配置文件 A-Star Dijkstra 算法原理
  12. linux opendir路径_Linux目录遍历opendir()
  13. MATLAB代码:基于分时电价条件下家庭能量管理策略研究
  14. asp实现注册登录界面_(01)ASP运行环境的搭建
  15. 计算机二级论文题,计算机二级考试真题-Word-小许-质量管理的论文
  16. 播放器显示服务器失败是什么意思,播放器没有办法播放
  17. 修复iPhone白苹果
  18. python操作键盘和鼠标_1、[python] PyMouse、PyKeyboard用python操作鼠标和键盘
  19. pip3 install XXX加快下载速度
  20. 177本名著浓缩成了177句话!经典收藏!太有道理了!

热门文章

  1. php表单实现分页,**PHP分步表单提交思路(分页表单提交)
  2. flutter 拖拽布局_Flutter 史上最牛拖动控件 Draggable
  3. graphpad7.04多组比较p值_R语言缺失值处理(MICE/Amelia/missForest/Hmisc/mi)
  4. 拆装计算机主机,台式计算机的拆装教案.doc
  5. transformers model inputs
  6. CUDA C编程权威指南 第一章
  7. chrome 设置user agent
  8. php 防止url输入,php防止伪造数据从地址栏URL提交的方法
  9. c语言 课程作业答案,《C语言程序设计A》课程形成性考核作业一参考答案
  10. react 生成图片二维码_21个React开发神器