并发编程 — volatile

[size=medium]
并发编程系列文章:
初解线程池:[url]http://ray-yui.iteye.com/blog/2072463[/url]
详解线程池:[url]http://ray-yui.iteye.com/blog/2075311[/url]
并发数据类型:[url]http://ray-yui.iteye.com/blog/2080454[/url]
并发数据结构:[url]http://ray-yui.iteye.com/blog/2084202[/url]
volatile:[url]http://ray-yui.iteye.com/blog/2231474[/url]
判断线程安全:[url]http://ray-yui.iteye.com/blog/2232931[/url]
实现线程安全:[url]http://ray-yui.iteye.com/blog/2234688[/url]
[/size]
[size=medium]
volatile是一个被遗忘的关键字,[color=red][b]在开发串行程序当中不会使用,而并行程序当中也不能代替锁(synchronized)(大多数情况下).但开发当中若然巧妙使用volatile,将避免不必要的加锁操作.[/b][/color]
[/size]
[size=medium]
在并行程序开发当中操作变量需要注意两个问题.一个是[color=red][b]安全性(正确性)[/b][/color],另一个是[color=red][b]内存可见性[/b][/color].当多个线程同时操作一个变量时,可以使用锁来保证操作变量的安全性和内存可见性,但若然当操作结果不需要依赖上一个结果,而仅仅只作为一个标识,则可以使用volatile来代替加锁.
[/size]
[size=medium]
以下代码不需要线程安全性,仅仅将变量作为退出线程的标识.但遗憾的是该程序有可能永远无法退出.
[/size]

public class Application {

private static boolean flag = false;
private static int number;

public static void main(String[] args) throws InterruptedException {
new Test().start();
Thread.sleep(1000);
number = 50;
flag = true;
}

private static class Test extends Thread {
@Override
public void run() {
while (!flag) {
System.out.println(number);
}
}
}
}

[size=medium]
volatile是Java提供的一种稍弱的同步机制,[color=red][b]用来增大被修饰变量的内存可见性,从而达到将变量的更新操作通知到其他线程.若然访问volatile修饰的变量将会到主存(堆)当中获取.而不会读取线程的变量副本,被修饰的变量亦不会被缓存到寄存器或者对其他处理器不可见的地方.[/b][/color]volatile只承诺被修饰变量的内存可见性,而不保证变量是否被正确的操作,因此volatile从语义或使用上都不能替代锁.因此当遇到以下场景时,可考虑使用volatile.
1.对变量的操作不依赖变量的当前值.
2.能确保只有一个线程对其进行修改.
3.修改变量不影响程序正确性.
[/size]
[size=medium]
总结:
在某些情况下使用volatile能避免不必要的加锁操作,尽管有更多或更好的方案代替volatile,但亦可以了解这个关键字的使用方法,必要时多一套解决方案.而在性能方面对比加锁的线程挂起/恢复开销,每次访问变量都需要去主存获取的volatile可以说是忽略不计.
[/size]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值