熟悉并发的同学一定知道在java中处理并发主要有两种方式:

1,synchronized关键字,这个大家应当都各种面试和笔试中经常遇到。

2,volatile修饰符的使用,相信这个修饰符大家平时在项目中使用的也不是很多。

这里重点说一下volatile:

Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存重新读取该成员的值,而且,当成员变量值发生变化时,强迫将变化的值重新写入共享内存(这边要注意一下,虽然是将变化的值写入到共享内存,但是写这个过程却不是同步的,也就是说这个写-set 值过程是不安全的),这样两个不同的线程在访问同一个共享变量的值时,始终看到的是同一个值(但由于前边写的是不安全的,所以只能保证多线程取-get 的是同一份,但不是说这个属性就是线程安全的,要想这个属性不仅仅取-get是安全的,而且set也是安全的话,就必须在属性的set方法上加synchronize锁才能真正意义上保证这个属性是线程安全的)。

java语言规范指出:为了获取最佳的运行速度,允许线程保留共享变量的副本,当这个线程进入或者离开同步代码块时,才与共享成员变量进行比对,如果有变化再更新共享成员变量。这样当多个线程同时访问一个共享变量时,可能会存在值不同步的现象。

而volatile这个值的作用就是告诉VM:对于这个成员变量不能保存它的副本,要直接与共享成员变量交互。 ---这仅是保证取的是安全的,不能保证set是安全的

建议:当多个线程同时访问一个共享变量时,可以使用volatile,而当访问的变量已在synchronized代码块中时,不必使用。

缺点:使用volatile将使得VM优化失去作用,导致效率较低,所以要在必要的时候使用,而且是 仅保证取是同步的,不能保证set是同步的,所以要想真正意义整体上的同步,必须在set方法上也加synchronize才行,验证set的不同步:比如i++操作的原子性验证,volatile解决的只是多线程间共享变量的可见性问题,自己可以随便写个用volatile修饰的变量,然后用多线程多跑i++,这种方法,很容易发现问题所在,即get 是同步,set是不同步的。

最新文章

  1. SQL作业的操作全
  2. linux下安装或升级GCC4.8,以支持C++11标准
  3. 关于actionscript中新建一个sprite,设置大小(宽高)的问题。
  4. hdu 5950 Recursive sequence 矩阵快速幂
  5. linux 命令小例
  6. 如何在linux系统下对文件夹名有空格的文件夹进行操作
  7. 使用Jena RDF API 开发脚本语言管理资源描述框架模型
  8. Asp.net的IP地址屏蔽功能设计
  9. xp下Oracle数据库导入SQLServer数据库数据
  10. java集合框架工具类Collections,集合的操作
  11. HanLP 自然语言处理 for nodejs
  12. CentOS7 常用设置
  13. 内省(Introspector)
  14. 一个数组中两个数的和为N,找出这两个数字的下标
  15. echarts 拼图和折线图的封装 及常规处理
  16. QT源码查看001-QApplication和QCoreApplication
  17. [性能调优]在PeopleSoft中使用函数索引
  18. Unity3D for Mac 破解
  19. iOS property中的strong 、weak、copy 、assign 、retain 、unsafe_unretained 与autoreleasing区别和作用详解
  20. August 16th 2017 Week 33rd Wednesday

热门文章

  1. Jenkins的制品管理
  2. Elasticsearch系列---使用中文分词器
  3. IdentityServer4源码解析_4_令牌发放接口
  4. 2020面试整理【java】
  5. OpenCV-Python 光流 | 四十八
  6. CSRF的几种防御方法的利弊分析
  7. js Object方法小结
  8. 二、【Docker笔记】Docker的核心概念及安装
  9. ConcurrentHashMap红黑树的实现
  10. JS 剑指Offer(一) 数组中的重复数字