Java中synchronized与volatile的区别与联系
来源:互联网 发布:无线怎么开启主人网络 编辑:程序博客网 时间:2024/05/17 17:59
在Java多线程编程中,synchronized是非常常用的关键字,而volatile关键字比较罕见。
volatile关键字用以避免因缓存(caching)或重排(reordering)而导致当前线程读取过时的数据。任何时候,线程读取的都是主线程内存中的最新数据。
在Java 1.5之前,多线程对volatile变量的访问是无法被重排的,但是对非volatile变量的访问是被重排的。这使得多线程在同时访问volatile变量和非volatile变量时,volatile变量无法被用作多线程的信号条件。因为虽然保证了volatile变量是最新的,但是不能保证非volatile变量是最新的。
从Java 1.5开始,volatile关键字被赋予了新的特性,更加接近synchronized的严格。对volatile变量的读操作就类似于对内存访问的加锁,对volatile变量的写就类似于对内存访问的释放锁。
由于对volatile变量和非volatile变量之间的重排设置了更加严格的限制,虽然volatile变量仍然无法被重排,但是对非volatile变量的重排也不那么容易了,从而使得volatile变量有可能作为信号条件。示例如下:
class VolatileExample { int x = 0; volatile boolean v = false; public void writer() { x = 42; v = true; } public void reader() { if (v == true) { //uses x - guaranteed to see 42. } }}
说明:由于在writer()方法中修改volatile变量v的同时,也修改了非volatile变量x,所以在Java 1.5中,对于执行reader()方法的线程来说,volatile变量v和非volatile变量x的最新值都是可见。而在Java 1.5之前,是无法保证非volatile变量x是最新值的。
当然,这也是有条件的,那就是多线程之间设置了准确的happens-before关系,即写入线程与读取线程操作的是同一个volatile变量v,即加的锁(类似锁但实际不是锁)与释放的锁匹配。
synchronized与volatile的主要区别有2点:
首先,从用法上,synchronized往往作用于方法或代码块,而volatile往往修饰变量。
其次,从实现机制上,synchronized是利用锁实现互斥访问。而volatile没有利用锁,而是利用内存共享,即volatile变量只在主线程中有一份,所有其他线程都共享这一份,因而一个线程对内存执行了写操作,所有其他线程立刻就能够读到最新的数据。
synchronized与volatile的对比:
参考文献:
https://www.cs.umd.edu/users/pugh/java/memoryModel/jsr-133-faq.html#volatile
- Java中synchronized与volatile的区别与联系
- volatile和synchronized的区别与联系
- volatile和synchronized的区别与联系
- volatile和synchronized的区别与联系
- java synchronized与volatile的区别
- volatile与synchronized的区别
- volatile与synchronized的区别
- volatile与synchronized的区别
- volatile与synchronized的区别
- synchronized与volatile的区别
- volatile与synchronized的区别
- volatile与synchronized的区别
- volatile与synchronized的区别
- Volatile与Synchronized的区别?
- volatile与synchronized的区别
- synchronized与volatile的区别
- volatile与synchronized的区别
- Java 中Synchronized 与 ReentrantLock 区别与联系
- 大话设计模式java版--适配器模式-关于不接口设计错误导致的处理方案
- 虚函数表
- Foundation => Objective-C - NSDate & NSCalendar
- 从安装到换主题的 5 个坑 -- 用Hexo建立自己的博客网站
- 高可用的工作心得分享
- Java中synchronized与volatile的区别与联系
- zzu 10480: 回文串 -- 模拟(最怕这种表面是算法,实际暴力的坑题)
- scrapy+Lucene搭建小型搜索引擎(现代信息检索大作业)
- Xcode之启动(打开)僵尸对象(Enable Zombie Objects)
- IO流
- HTTP实用头字段
- Java之数组
- Spark中parallelize函数和makeRDD函数的区别
- jQuery是什么