volatile与synchronized的区别

来源:互联网 发布:二维数组分配空间 编辑:程序博客网 时间:2024/05/17 23:06

1,volatile 详解
[http://blog.csdn.net/hqfok/article/details/73497732]
这里简单说一下重点:
处理器为了提高处理速度,不直接和内存进行通讯,而是先将系统内存的数据读到内部缓存(L1,L2或其他)后再进行操作,但操作完之后不知道何时会写到内存,如果对声明了Volatile变量进行写操作,JVM就会向处理器发送一条Lock前缀的指令,将这个变量所在缓存行的数据写回到系统内存。但是就算写回到内存,如果其他处理器缓存的值还是旧的,再执行计算操作就会有问题,所以在多处理器下,为了保证各个处理器的缓存是一致的,就会实现缓存一致性协议,每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,当处理器要对这个数据进行修改操作的时候,会强制重新从系统内存里把数据读到处理器缓存里

2,锁的特性分两种:

(1)互斥锁

使用synchronized 咱们可以知道 同一个时间只允许单线程调用 synchronized 修饰的方法或者其他代码块。

(2)可见性锁

使用volatile 是表示多可线程 对volatile 修饰的变量是可见的,意思就是说 ThreadA ThreadB ThreadC 在volatile 的value 发生变化的时候 都能够第一时间知道。就是上边所说的重点(有点绕口 好好理解一下)。当声明了Volatile的时候 ThreadA 对变量 volatileValue 进行了修改。比如说volatile初始为1现在改为2 jvm向处理器发送一条Lock 前缀指令,将变量所在缓存行的数据协会到系统内存,当ThreadB ThreadC 对volatileValue 进行使用的时候 处理器缓存的值是旧的(原因参考 volatile 详解中链接 一个处理器的缓存回写到内存会导致其他处理器的缓存无效 部分)就会从内存中强制把数据读到处理器缓存中。就可以同步的使用了。

总结:

1,volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞.

2,volatile本质是在告诉jvm当前变量在缓存中的值不确定,当缓存中变量过期后就会强制从内存中读取,synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住.

3,volatile仅能使用在变量级别,synchronized则可以使用在变量,方法.

4,volatile仅能实现变量的修改可见性,而synchronized则可以保证变量的修改可见性和原子性.