理解Java原子性访问

泪湿孤枕 提交于 2020-12-02 17:38:38

在编程中,一个原子动作是一个有效地同时发生的动作。一个原子动作不能中途停止:它要么完全发生,要么根本不发生。在动作完成之前,原子动作的任何副作用都是不可见的。

我们已经看到,一个增量表达式,如a++,并不能描述一个原子动作。即使是非常简单的表达式也可以定义复杂的动作,这些动作可以分解为其他动作。然而,你可以指定一些动作是原子的:

  • 对于引用变量和大多数原始变量(除了longdouble以外的所有类型)的读和写都是原子性的。
  • 对于所有声明为volatile的变量(包括long变量和double变量),读和写都是原子性的。

原子操作不能交错,所以可以不用担心线程干扰。然而,这并不能消除所有同步原子动作的需要,因为内存一致性错误仍然可能发生。使用volatile变量可以降低内存一致性错误的风险,因为对volatile变量的任何写都会与该变量的后续读建立一个发生在前的关系。这意味着对volatile变量的更改总是对其他线程可见。更重要的是,这也意味着当一个线程读取一个volatile变量时,它不仅能看到volatile变量的最新变化,还能看到导致该变化的代码的副作用。

使用简单的原子变量访问比通过同步代码访问这些变量更有效率,但需要程序员更加小心,以避免内存一致性错误。额外的努力是否值得,取决于应用程序的大小和复杂程度。

此Java教程是为JDK 8编写的。本页中描述的示例和实践并没有利用以后版本中引入的改进,可能会使用不再可用的技术。
请参见 Java 语言变更,以了解 Java SE 9 及其后续版本中更新的语言功能的摘要。
请参见 JDK 发行说明,了解有关所有 JDK 发行版的新功能、增强功能以及删除或废弃选项的信息。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!