恐怕比较一下volatile和synchronized的不同是最容易解释清楚的。volatile是变量修饰符,而synchronized则作用于一段代码或方法;看如下三句get代码:

  1. int i1;              int geti1() {return i1;}
  2. volatile int i2;  int geti2() {return i2;}
  3. int i3;              synchronized int geti3() {return i3;}

  geti1()得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以互不相同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。事实上,Java有个思想叫“主”内存区域,这里存放了变量目前的“准确值”。每个线程可以有它自己的变量拷贝,而这个变量拷贝值可以和“主”内存区域里存放的不同。因此实际上存在一种可能:“主”内存区域里的i1值是1,线程1里的i1值是2,线程2里的i1值是3——这在线程1和线程2都改变了它们各自的i1值,而且这个改变还没来得及传递给“主”内存区域或其他线程时就会发生。               

而geti2()得到的是“主”内存区域的i2数值。用volatile修饰后的变量不允许有不同于“主”内存区域的变量拷贝。换句话说,一个变量经volatile修饰后在所有线程中必须是同步的;任何线程中改变了它的值,所有其他线程立即获取到了相同的值。理所当然的,volatile修饰的变量存取时比一般变量消耗的资源要多一点,因为线程有它自己的变量拷贝更为高效。               

既然volatile关键字已经实现了线程间数据同步,又要synchronized干什么呢?呵呵,它们之间有两点不同。首先,synchronized获得并释放监视器——如果两个线程使用了同一个对象锁,监视器能强制保证代码块同时只被一个线程所执行——这是众所周知的事实。但是,synchronized也同步内存:事实上,synchronized在“主”内存区域同步整个线程的内存。因此,执行geti3()方法做了如下几步:

1. 线程请求获得监视this对象的对象锁(假设未被锁,否则线程等待直到锁释放)

2. 线程内存的数据被消除,从“主”内存区域中读入(Java虚拟机能优化此步。。。[后面的不知道怎么表达,汗])

3. 代码块被执行

4. 对于变量的任何改变现在可以安全地写到“主”内存区域中(不过geti3()方法不会改变变量值)

5. 线程释放监视this对象的对象锁               

因此volatile只是在线程内存和“主”内存间同步某个变量的值,而synchronized通过锁定和解锁某个监视器同步所有变量的值。显然synchronized要比volatile消耗更多资源。

最新文章

  1. iOS UIPageViewController
  2. Hadoop原理介绍
  3. Flowplayer-一款免费的WEB视频播放器
  4. Java实现文件压缩与解压[zip格式,gzip格式]
  5. 构建通过 Database.com 提供技术支持的 PhoneGap 应用程序
  6. Configurataion Printer(基于全新2.2.0API)
  7. DNA Sequence - POJ 2778(AC自动机+矩阵乘法)
  8. 深入剖析PE文件
  9. Chapter 2 Open Book——14
  10. 【打死树莓派】-树莓派3代jessie+Opencv-解决安装不了libgtk2.0-dev包问题
  11. Android java.io.FileNotFoundException:*** (Permission denied)
  12. CentOS 7 Redis安装配置
  13. Linux 库函数与系统调用的关系与区别
  14. go语言调度器源代码情景分析之五:汇编指令
  15. scala使用slick查询的全过程(使用cass class)
  16. 进入jsp页面的6种方法
  17. docker 搭建maven 私服
  18. Zookeeper客户端Curator---Getting Started
  19. ceph 对象存储跨机房容灾
  20. [待完善]mycat使用(一)

热门文章

  1. SQL必知必会 14-22(完)
  2. 常用算法——排序(二)
  3. [KMP]【学习笔记】
  4. jdbc java数据库连接 11)中大文本类型的处理
  5. 使用 iscroll 实现焦点图无限循环
  6. FineUI(专业版)v3.0.0 发布,手机、平板和桌面全支持!
  7. ping环回地址和ping主机地址的区别
  8. 时间格式转换—将后台返回的/Date(1448954018000)/格式转换为正常的时间格式
  9. [转] eclipse SVN中文件修改后图标不变黑星解决
  10. virtualenv 安装使用