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

java 多线程 原子性和易变性的理解(还有可视性)本文深入探讨了 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
编程小号
上一篇 2025-01-10 17:57
下一篇 2025-01-10 17:46

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/107203.html