java 多线程 原子性和易变性的理解(还有可视性)

    volatile关键字还确保了应用中的可视性。如果你将一个域声明为volatile的,那么只要对这个域产生了写操作,那么所有的读操作就都可以
看到这个修改。即便使用了本地缓存,情况也确实如此,volatile域会立即被写入到主存中,而读取操作就发生在主存中。
    理解原子性和易变性是不同的概念这一点很重要。在非volatile域上的原子操作不必刷新到主存中去,因此其他读取该域的任务也不必看到这
个新值。如果多个任务在同事访问某个域,那么这个域就应该是volatile的,否则,这个域就应该只能经由同步来访问。同步也会导致主存中刷新,
因此如果一个域完全由synchronized方法或语句块来防护,那就不必将其设置为是volatile的。
    一个任务所作的任何写入操作对这个任务来说都是可视的,因此如果它只需要在这个任务内部可视,那么你就不需要将其设置为volatile的。
    当一个域的值依赖于它之前的值时(例如递增一个计数器),volatile就无法工作了。如果某个域的值受到其他域的值的限制,那么volatile
也无法工作,例如Range类的lower和upper边界就必须遵循lower<=upper的限制。
    使用volatile而不是synchronized的唯一安全的情况是类中只有一个可变的域。再次提醒,你的第一个选择应该是使用synchronized关键字,
这是最安全的方式,而尝试其他任何方式都是有风险的。
    什么才属于原子操作呢?对域中的值做赋值和返回操作通常都是原子性的,但是,在C++中,i++;i+=2都可能是原子性的。但是在C++中,这要
取决于编译器和处理器。你无法编写依赖于原子性的C++跨平台代码,因为C++没有像Java(在Java SE5中)那样一致的内存模型。

    在Java中,上面的操作可能不是原子性的,正如下面的方法所阐释的JVM指令中可以看到的那样:

    //concurrency / Atomicity.java
    //{Exec: javap -c Atomicity}
    public class Atomicity{
		int i
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值