【翻译十一】java-原子性操作

  

Atomic Access

In programming, an atomic action is one that effectively happens all at once. An atomic action cannot stop in the middle: it either happens completely, or it doesn't happen at all. No side effects of an atomic action are visible until the action is complete.

We have already seen that an increment expression, such as c++, does not describe an atomic action. Even very simple expressions can define complex actions that can decompose into other actions. However, there are actions you can specify that are atomic:

  • Reads and writes are atomic for reference variables and for most primitive variables (all types except long anddouble).
  • Reads and writes are atomic for all variables declared volatile (including long and double variables).

Atomic actions cannot be interleaved, so they can be used without fear of thread interference. However, this does not eliminate all need to synchronize atomic actions, because memory consistency errors are still possible. Using volatilevariables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable. This means that changes to a volatile variable are always visible to other threads. What's more, it also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.

Using simple atomic variable access is more efficient than accessing these variables through synchronized code, but requires more care by the programmer to avoid memory consistency errors. Whether the extra effort is worthwhile depends on the size and complexity of the application.

Some of the classes in the java.util.concurrent package provide atomic methods that do not rely on synchronization. We'll discuss them in the section on High Level Concurrency Objects.

 
译文:
原子操作
 在编程中,原子操作指动作只有效的发生一次。原子操作不能在中途停止。它要么完全发生,要么不发生。直到这个原子性早错完成之后才是可见的。
我们已经看到了一种自增运算,例如C++,不是原子性操作,即使是很简单的表达式,也可以分解成复杂的操作。但是,这里提供了指定操作为原子性操作的方法。
  • 读取和写入原子性的引用变量和最基础的变量类型(除了long和double).
  • 读取和写入原子性的带有volatile声明的变量 (包括 long 和double 变量).

原子性操作不会出现交叉,因此不会出现线程交叉性冲突。然而,这并不能消除原子性操作需要用synchroinze方法限制,因为内存一致性错误仍然还是存在的。使用volatile变量降低了内存一致性错误,因为volatile变量在写入的时候就确定了对于后续操作这个变量的事先发生的关系。这以为对于volatile变量的改变,对于其他线程始终是可见的。更重要的是,当一个线程读取volatile变量的时候,它不仅看到了这个变量最新的改变,而且能够在它的代码中改变这个变量的值。

利用简单的原子性操作比用synchroinze方法更加的有效率,但是,要求程序员更加的注意内存一致性错误。是否更多的工作需要做,依赖于应用程序的大小和复杂性。

许多在java.util.concurrent包中的类提供了不依赖于synchroinze的原子性方法。我们会在 High Level Concurrency Objects这一节讲述这些方法。

简历: 三年国内著名软件公司Java信息系统开发经验。熟悉税务相关业务知识。一年以上互联网公司工作经验。 目标职位: Java研发工程师、大数据、推荐算法等。 目标城市: 北京,杭州,沈阳。 联系方式: 邮箱:hecuking@126.com
原文地址:https://www.cnblogs.com/accipiter/p/3204015.html