美文网首页
原子操作类-总结

原子操作类-总结

作者: 王侦 | 来源:发表于2019-07-17 17:17 被阅读0次

1.官方描述

1.1 单个变量AtomicBoolean, AtomicInteger, AtomicLong和AtomicReference

A small toolkit of classes that support lock-free thread-safe 
programming on single variables. In essence, the classes in this 
package extend the notion of volatile values, fields, and array 
elements to those that also provide an atomic conditional update 
operation of the form:

  boolean compareAndSet(expectedValue, updateValue);

This method (which varies in argument types across different 
classes) atomically sets a variable to the updateValue if it 
currently holds the expectedValue, reporting true on success. The 
classes in this package also contain methods to get and 
unconditionally set values, as well as a weaker conditional atomic 
update operation weakCompareAndSet described below.

The specifications of these methods enable implementations to 
employ efficient machine-level atomic instructions that are 
available on contemporary processors. However on some 
platforms, support may entail some form of internal locking. Thus 
the methods are not strictly guaranteed to be non-blocking -- a 
thread may block transiently before performing the operation.

支持对单变量无锁线程安全编程。使用CAS拓展了volatile概念。

CAS一般采用高效机器级原子指令实现,但是在某些平台,可能需要内部锁来支持。因此,不严格保证方法是非阻塞的,线程可能在执行操作之前暂时阻塞。

Instances of classes AtomicBoolean, AtomicInteger, AtomicLong, 
and AtomicReference each provide access and updates to a 
single variable of the corresponding type. Each class also 
provides appropriate utility methods for that type. For example, 
classes AtomicLong and AtomicInteger provide atomic increment 
methods. One application is to generate sequence numbers, as 
in:

类AtomicBoolean, AtomicInteger, AtomicLong和AtomicReference的实例分别提供了对相应类型的单个变量的访问和更新,每个类还为该类型提供了适当的实用方法。例如,AtomicBoolean, AtomicInteger提供了原子增量方法。

 class Sequencer {
   private final AtomicLong sequenceNumber
     = new AtomicLong(0);
   public long next() {
     return sequenceNumber.getAndIncrement();
   }
 }
It is straightforward to define new utility functions that, like 
getAndIncrement, apply a function to a value atomically. For 
example, given some transformation

  long transform(long input)

定义新的实用程序函数很简单,像getAndIncrement,将函数原子地应用于值。

write your utility method as follows:

 long getAndTransform(AtomicLong var) {
   long prev, next;
   do {
     prev = var.get();
     next = transform(prev);
   } while (!var.compareAndSet(prev, next));
   return prev; // return next; for transformAndGet
 }
The memory effects for accesses and updates of atomics 
generally follow the rules for volatiles, as stated in The Java 
Language Specification (17.4 Memory Model):

* get has the memory effects of reading a volatile variable.
* set has the memory effects of writing (assigning) a volatile variable.
* lazySet has the memory effects of writing (assigning) a volatile 
  variable except that it permits reorderings with subsequent (but 
  not previous) memory actions that do not themselves impose 
  reordering constraints with ordinary non-volatile writes. Among 
  other usage contexts, lazySet may apply when nulling out, for the 
  sake of garbage collection, a reference that is never accessed 
  again.
* weakCompareAndSet atomically reads and conditionally writes 
  a variable but does not create any happens-before orderings, so 
  provides no guarantees with respect to previous or subsequent 
  reads and writes of any variables other than the target of the 
  weakCompareAndSet.
* compareAndSet and all other read-and-update operations such 
  as getAndIncrement have the memory effects of both reading and 
  writing volatile variables.

访问和更新原子类的内存效应遵循volatile的规则,如果Java语言规范中所述(17.4 Memory Model):

  • get等同于从volatile中读
  • set等同于写volatile
  • lazySet等同于写volatile,除了允许后续(不是前面的)内存操作重排序,这些内存操作不会对普通的non-volatile写施加重排序约束。在其他用法中,为了垃圾回收,lazySet可以在使一个不会再访问的引用置为null时使用。
  • weakCompareAndSet原子读并有条件地写,但不会创建任何happens-before顺序,因此不会提供任何保证(与先前和后续的任何变量的读写)
  • compareAndSet以及其他所有读取并更新的操作都具有读写volatile的内存效应。

1.2 域AtomicReferenceFieldUpdater, AtomicIntegerFieldUpdater及AtomicLongFieldUpdater

In addition to classes representing single values, this package 
contains Updater classes that can be used to obtain 
compareAndSet operations on any selected volatile field of any 
selected class. AtomicReferenceFieldUpdater, 
AtomicIntegerFieldUpdater, and AtomicLongFieldUpdater are 
reflection-based utilities that provide access to the associated 
field types. These are mainly of use in atomic data structures in 
which several volatile fields of the same node (for example, the 
links of a tree node) are independently subject to atomic updates.
 These classes enable greater flexibility in how and when to use 
atomic updates, at the expense of more awkward reflection-
based setup, less convenient usage, and weaker guarantees.

可以在任何类的volatile域上执行CAS操作。AtomicReferenceFieldUpdater, AtomicIntegerFieldUpdater及AtomicLongFieldUpdater这三个类是基于反射的,可提供对相关字段的访问。通常用于原子数据结构,在同一结点中有几个volatile域,可以独立地进行原子更新。这些类在如何以及何时使用原子更新方面提供了更大的灵活性,代价是笨拙的基于反射的设置,不太方便的使用和较弱的保证。

1.3 数组AtomicIntegerArray, AtomicLongArray和AtomicReferenceArray

The AtomicIntegerArray, AtomicLongArray, and 
AtomicReferenceArray classes further extend atomic operation 
support to arrays of these types. These classes are also notable
 in providing volatile access semantics for their array elements, 
which is not supported for ordinary arrays.

1.4 weakCompareAndSet

The atomic classes also support method weakCompareAndSet, 
which has limited applicability. On some platforms, the weak 
version may be more efficient than compareAndSet in the normal 
case, but differs in that any given invocation of the 
weakCompareAndSet method may return false spuriously (that is, 
for no apparent reason). A false return means only that the 
operation may be retried if desired, relying on the guarantee that 
repeated invocation when the variable holds expectedValue and 
no other thread is also attempting to set the variable will 
eventually succeed. (Such spurious failures may for example be 
due to memory contention effects that are unrelated to whether 
the expected and current values are equal.) Additionally 
weakCompareAndSet does not provide ordering guarantees that 
are usually needed for synchronization control. However, the 
method may be useful for updating counters and statistics when 
such updates are unrelated to the other happens-before 
orderings of a program. When a thread sees an update to an 
atomic variable caused by a weakCompareAndSet, it does not 
necessarily see updates to any other variables that occurred 
before the weakCompareAndSet. This may be acceptable when, 
for example, updating performance statistics, but rarely 
otherwise.

weakCompareAndSet适用性有限。在某些平台上,弱版本可能比普通情况下的compareAndSet更高效,但不同之处在于,任何给定的weakCompareAndSet方法调用都可能虚假地返回false(没有明显的原因)。错误返回仅表示如果需要可以重试操作,依赖于如下保证:当变量保持expectedValue时没有其他线程尝试设置变量,重复调用最终会成功。(例如,这种虚假故障可能是由于与预期值和当前值相等无关的内存争用效应。)另外,weakCompareAndSet不提供同步控制通常需要的排序保证。然而,该方法对于更新计数器和统计数据可能是有用的,当这些更新与其他程序的happens-before顺序无关时。当线程看到由weakCompareAndSet引起的原子变量更新时,它不必一定得看到在weakCompareAndSet之前发生的任何其他变量的更新。这在某些情况下是可接受的,例如更新性能统计信息,在其他情况下很少。

1.5 关联标记AtomicMarkableReference和AtomicStampedReference

The AtomicMarkableReference class associates a single boolean 
with a reference. For example, this bit might be used inside a 
data structure to mean that the object being referenced has 
logically been deleted. The AtomicStampedReference class 
associates an integer value with a reference. This may be used 
for example, to represent version numbers corresponding to 
series of updates.

AtomicMarkableReference类将单个布尔值与引用相关联。该位可在数据结构中表示被引用的对象在逻辑上是否已被删除。 AtomicStampedReference类将整数值与引用相关联。可用于表示与一系列更新相对应的版本号。

1.6 注意事项

Atomic classes are designed primarily as building blocks for 
implementing non-blocking data structures and related 
infrastructure classes. The compareAndSet method is not a 
general replacement for locking. It applies only when critical 
updates for an object are confined to a single variable.

Atomic classes are not general purpose replacements for 
java.lang.Integer and related classes. They do not define 
methods such as equals, hashCode and compareTo. (Because 
atomic variables are expected to be mutated, they are poor 
choices for hash table keys.) Additionally, classes are provided 
only for those types that are commonly useful in intended 
applications. For example, there is no atomic class for 
representing byte. In those infrequent cases where you would like 
to do so, you can use an AtomicInteger to hold byte values, and 
cast appropriately. You can also hold floats using 
Float.floatToRawIntBits(float) and Float.intBitsToFloat(int) 
conversions, and doubles using 
Double.doubleToRawLongBits(double) and 
Double.longBitsToDouble(long) conversions.
  • 原子类主要设计为用于实现非阻塞数据结构和相关基础结构类的构建块。 compareAndSet方法不是锁的通用替代方法。仅当对象的关键更新仅限于单个变量时,它才适用。
  • 原子类不是java.lang.Integer和相关类的通用替换。它们没有定义equals,hashCode和compareTo等方法。 (因为预期原子变量会发生变化,所以它们不适用于作为哈希表的键。)
  • 另外,只为那些常用的类型提供了对应的原子类。在某些罕见需要使用其他类型的原子类时,可使用这些类进行类型转换。
    Float.floatToRawIntBits(float);Float.intBitsToFloat(int)
    Double.doubleToRawLongBits(double);Double.longBitsToDouble(long)

2.消耗对比

对于CPU的消耗来说,其从小到大依次为:

  • long: 最小, 多线程不安全
  • volatile long: 消耗 > long, 多线程读取安全,但无法进行原子操作
  • AtomicLong:消耗 > volatile long,多线程读安全,可进行原子操作
  • AtomicLongFieldUpdate:消耗 > AtomicLong,因为其使用反射技术,多线程安全和可原子操作

3.AtomicReferenceFieldUpdater, AtomicIntegerFieldUpdater及AtomicLongFieldUpdater弱保证性

Note that the guarantees of the compareAndSet method in this 
class are weaker than in other atomic classes. Because this class 
cannot ensure that all uses of the field are appropriate for 
purposes of atomic access, it can guarantee atomicity only with 
respect to other invocations of compareAndSet and set on the 
same updater.

请注意,此类中compareAndSet方法的保证比其他原子类弱。 因为此类无法确保该字段的所有使用都适用于原子访问的目的,只能保证相同updater上执行CAS和set操作的原子性,因此它的原子性是弱于AtomicLong的。

AtomicLong是对long型属性加了一层原子引用,任何想要修改该long值的操作都需要先获得该原子引用,而updater不会为属性增加原子引用,它是通过反射技术,通过外部操作去修改long型属性值,因此它的原子保证也是通过外部限制的,因此只能保证同一updater进行CAS和set的原子性。

相关文章

  • 原子操作类-总结

    1.官方描述 1.1 单个变量AtomicBoolean, AtomicInteger, AtomicLong和A...

  • 高并发(12)-原子操作类的使用

    @TOC 前言 上篇文章讲解了什么是原子操作,并且怎么实现原子操作。今天就讲一下原子的操作类 什么是原子操作类 为...

  • Java并发 之 Atomic 原子操作类

    Atomic 原子操作类 在java.util.concurrent.atomic包里提供了一组原子操作类,这些类...

  • 原子操作类

    原子操作类简介 在并发编程中很容易出现并发安全的问题,有一个很简单的例子就是多线程更新变量i=1,比如多个线程执行...

  • Java - 原子操作类

    Java中的12个原子操作类 原子更新基本类型类 AtomicBoolean:原子更新布尔类型 AtomicInt...

  • Java原子类

    1、原子类的分类 原子操作是指一个不可中断的操作。 原子类是指具有原子操作特征的类。 JUC并发包中的原子类都存放...

  • 多线程并发编程4-原子操作类源码剖析

    今天来讲一讲原子操作类,JUC包提供了一系列的原子性操作类,这些操作类使用的是CAS非阻塞算法实现的,相比于锁...

  • 【Java源码计划】AtomicInteger<rt.ja

    AtomicInteger 这个类是Automic包下的类,用于提供对应类型的原子操作 这个类提供了整形的原子更新...

  • Java 原子操作类

    概述 java.util.concurrent.atomic 包一共提供了 13 个类,属于 4 种类型的原子更新...

  • 原子操作类-引用

    1.AtomicReference大部分方法带有Object标识 设置引用调用的是getAndSetObject,...

网友评论

      本文标题:原子操作类-总结

      本文链接:https://www.haomeiwen.com/subject/mnzqlctx.html