您的位置:首页 > 编程语言

还在使用 Synchronized同步?试试 Volatile 吧,让你的代码更高效

2016-12-09 14:47 351 查看
Synchronized

运用synchronized关键字来实现同步块,大家都比较熟悉。为了避免多线程 同一时间 访问 同一方法或代码块时,方法产生和预期不同的结果,我们一般在这一方法或者代码块前使用synchronized关键字来修饰,从而保证方法或者代码块同一时刻只能有一个线程可以使用。

synchronized 三大特性:地址 地址

可见性:synchronized能够保证同步块中的变量,发生变化后立即同步到主存(即变量的本身)

原子性:java中对原子性描述有两层含义

1、一组语句作为单独的不可分割的单元运行

2、一个由同一个锁保护的synchronized块一次只能由一个线程执行

有序性:顾名思义synchronized修饰的代码块,会阻塞线程,只有待前一个线程执行完毕才会让后一个线程进入。

推荐一篇synchronized的博客:地址

Volatile

用volatile修饰的变了,线程在每次使用的时候,都会读取变量修改后的最新值。volatile具备synchronized的可见性,

在特定的情况下,他同样具备和synchronized一样的原子性,(例如:对任意的单个volatile变量的读、写具有原子性,但是类似a++这样的复合操作是不具备原子性的)

正确的使用volatile变量

volatile变量可用于提供线程安全,但是只能应用玉非常有限的一组用列:多个变量之间或者某个变量的当前值与修改后的值之间没有约束。所以,单独使用volatile是不足以实现计数器、互斥锁或者任何具有与多个变量相关的不变式的类

在满足以下两个条件下,你可以使用volatile变量来替代锁,从而提供理想的线程安全

1、对变量的写的操作不依赖玉当前的值

2、该变量没有包含在具体有其他变量的不变式中

这条件就说明,可以被写入volatile变量的这些幼小值独立于任何程序的状态,包括变量的当前状态

第一个条件的限制使volatile变量不能用作线程安全计数器。虽然增量操作(a++)看上去类似于一个独立的操作,实际上它是由 读取-修改-写入操作序列组成的操作组合,必须以圆子的方式执行,而这时候volatile不能剔骨必须的原子性。实现正确的操作需要使用a的值在操作期间保持不变,但是volatile变量无法做到这点。(但是把修改成只从单线写入,第一个条件就可以忽略)

推荐博客:地址 地址 地址 地址

Such as:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息