JDK1.8的Java.util.concurrent.atomic包小结

Atomic意为原子的,JUC包又是并发包,所以不必多说。

Atomic的特点

①多线程环境下,无所的进行原子操作。
②不能绝对保证线程不被阻塞。(因不同CPU的原子指令不同,可能需要某种形式的内部锁)

Atomic下有哪些类

13个实现类:

AtomicBoolean

@since 1.5

/**
 * A {@code boolean} value that may be updated atomically. See the
 * {@link java.util.concurrent.atomic} package specification for
 * description of the properties of atomic variables. An
 * {@code AtomicBoolean} is used in applications such as atomically
 * updated flags, and cannot be used as a replacement for a
 * {@link java.lang.Boolean}.
 *
 * @since 1.5
 * @author Doug Lea
 */

自己翻译: 一、可能以原子方式更新。
          二、不能当作Boolean的替代品

AtomicInteger

@since 1.5

 However, this class does extend
{@code Number} to allow uniform access by tools and utilities that
  deal with numerically-based classes.

特点:
自己翻译: 一、可能以原子方式更新。
          二、不能当作Integer的替代品
          三、类继承自Number,允许被以数值为基础的 classes文件 当做工具类去使用

AtomicIntegerArray

@since 1.5

特点:
自己翻译: 可能以原子方式更新。

这个类通常被用作

AtomicLong

@since 1.5

特点:
自己翻译: 一、可能以原子方式更新。
          二、不能当作Long的替代品
          三、类继承自Number,允许被以数值为基础的 classes文件 当做工具类去使用

AtomicLongArray

@since 1.5

特点:
自己翻译: 可能以原子方式更新。

这个类通常被用作

AtomicMarkableReference


@since 1.5

/**
 * An {@code AtomicMarkableReference} maintains an object reference
 * along with a mark bit, that can be updated atomically.
 *
 * 

Implementation note: This implementation maintains markable * references by creating internal objects representing "boxed" * [reference, boolean] pairs. * * @since 1.5 * @author Doug Lea * @param The type of object referred to by this reference */ 一、维护一个对象引用,加上一个标记位,除了标记位外,还可以进行原子更新。 二、该实现通过创建表示“装箱”(引用、布尔)对的内部对象来保持标记引用。

AtomicReference

@since 1.5

一、可以以原子方式更新的对象引用

AtomicReferenceArray

@since 1.5
一、可以以原子方式更新的对象引用

AtomicStampedReference

@since 1.5

一、保持一个对象引用和一个整数“戳记”,可以以原子的方式更新。
二、实现说明:这个实现通过创建表示“装箱”(引用、整数)对的内部对象来维护标记引用。

DoubleAccumulator

@since 1.8

/**
 * One or more variables that together maintain a running {@code double}
 * value updated using a supplied function.  When updates (method
 * {@link #accumulate}) are contended across threads, the set of variables
 * may grow dynamically to reduce contention.  Method {@link #get}
 * (or, equivalently, {@link #doubleValue}) returns the current value
 * across the variables maintaining updates.
 *
 * 

This class is usually preferable to alternatives when multiple * threads update a common value that is used for purposes such as * summary statistics that are frequently updated but less frequently * read. * *

The supplied accumulator function should be side-effect-free, * since it may be re-applied when attempted updates fail due to * contention among threads. The function is applied with the current * value as its first argument, and the given update as the second * argument. For example, to maintain a running maximum value, you * could supply {@code Double::max} along with {@code * Double.NEGATIVE_INFINITY} as the identity. The order of * accumulation within or across threads is not guaranteed. Thus, this * class may not be applicable if numerical stability is required, * especially when combining values of substantially different orders * of magnitude. * *

Class {@link DoubleAdder} provides analogs of the functionality * of this class for the common special case of maintaining sums. The * call {@code new DoubleAdder()} is equivalent to {@code new * DoubleAccumulator((x, y) -> x + y, 0.0)}. * *

This class extends {@link Number}, but does not define * methods such as {@code equals}, {@code hashCode} and {@code * compareTo} because instances are expected to be mutated, and so are * not useful as collection keys. * * @since 1.8 * @author Doug Lea */ 一个或多个变量,共同维护一个运行的{@ code double}值,使用提供的函数更新。当更新(方法{@ link #积累})在线程之间进行争用时,变量集可以动态增长以减少争用。方法{@ link # get}(或者,相当地,{@ link # doubleValue})返回当前的值,以保持更新。 当多个线程更新一个共同的值时,这个类通常比其他方法更可取,比如经常更新但不经常读取的汇总统计信息。 提供的累加器函数应该是无副作用的,因为在尝试更新失败时,由于线程之间的争用,它可能会被重新应用。函数以当前值作为其第一个参数,而给定的update作为第二个参数。例如,为了维持一个运行最大值,您可以提供{@ code Double::max}和{@ code Double。NEGATIVE_INFINITY }的身份。在线程内部或跨线程中积累的顺序没有保证。因此,这 如果需要数值稳定性,则类可能不适用,特别是当组合了大量不同的值时 的大小。类{@ link DoubleAdder}为维护和的共同特殊情况提供了该类的类似功能。调用{@ code新的DoubleAdder()}相当于{@ code new double累加器((x,y)- > x + y,0.0)}。 这个类扩展了{@ link Number},但是< em >不是< /em >定义了诸如{@ code =}、{@ code hashCode}和{@ code compareTo}之类的方法,因为实例被期望发生突变,因此不作为集合键有用。

DoubleAdder

@since 1.8

/**
 * One or more variables that together maintain an initially zero
 * {@code double} sum.  When updates (method {@link #add}) are
 * contended across threads, the set of variables may grow dynamically
 * to reduce contention.  Method {@link #sum} (or, equivalently {@link
 * #doubleValue}) returns the current total combined across the
 * variables maintaining the sum. The order of accumulation within or
 * across threads is not guaranteed. Thus, this class may not be
 * applicable if numerical stability is required, especially when
 * combining values of substantially different orders of magnitude.
 *
 * 

This class is usually preferable to alternatives when multiple * threads update a common value that is used for purposes such as * summary statistics that are frequently updated but less frequently * read. * *

This class extends {@link Number}, but does not define * methods such as {@code equals}, {@code hashCode} and {@code * compareTo} because instances are expected to be mutated, and so are * not useful as collection keys. * * @since 1.8 * @author Doug Lea */ 一个或多个变量一起维护一个初始的零{@ code double} sum。当更新(方法{@ link # add})在线程之间进行争用时,变量集可以动态增长以减少争用。方法{@ link # sum}(或者,等价{@ link # doubleValue})将当前的总数组合在维持总和的变量上。在线程内部或跨线程中积累的顺序没有保证。因此,如果需要数值稳定性,这个类可能不适用,特别是当组合了大量不同数量级的值时。 当多个线程更新一个共同的值时,这个类通常比其他方法更可取,比如经常更新但不太频繁的汇总统计数据 这个类扩展了{@ link Number},但是< em >不是< /em >定义了诸如{@ code =}、{@ code hashCode}和{@ code compareTo}之类的方法,因为实例被期望发生突变,因此不作为集合键有用。

LongAccumulator


@since 1.8

/**
 * One or more variables that together maintain a running {@code long}
 * value updated using a supplied function.  When updates (method
 * {@link #accumulate}) are contended across threads, the set of variables
 * may grow dynamically to reduce contention.  Method {@link #get}
 * (or, equivalently, {@link #longValue}) returns the current value
 * across the variables maintaining updates.
 *
 * 

This class is usually preferable to {@link AtomicLong} when * multiple threads update a common value that is used for purposes such * as collecting statistics, not for fine-grained synchronization * control. Under low update contention, the two classes have similar * characteristics. But under high contention, expected throughput of * this class is significantly higher, at the expense of higher space * consumption. * *

The order of accumulation within or across threads is not * guaranteed and cannot be depended upon, so this class is only * applicable to functions for which the order of accumulation does * not matter. The supplied accumulator function should be * side-effect-free, since it may be re-applied when attempted updates * fail due to contention among threads. The function is applied with * the current value as its first argument, and the given update as * the second argument. For example, to maintain a running maximum * value, you could supply {@code Long::max} along with {@code * Long.MIN_VALUE} as the identity. * *

Class {@link LongAdder} provides analogs of the functionality of * this class for the common special case of maintaining counts and * sums. The call {@code new LongAdder()} is equivalent to {@code new * LongAccumulator((x, y) -> x + y, 0L}. * *

This class extends {@link Number}, but does not define * methods such as {@code equals}, {@code hashCode} and {@code * compareTo} because instances are expected to be mutated, and so are * not useful as collection keys. * * @since 1.8 * @author Doug Lea */

LongAdder

@since 1.8
/**
 * One or more variables that together maintain an initially zero
 * {@code long} sum.  When updates (method {@link #add}) are contended
 * across threads, the set of variables may grow dynamically to reduce
 * contention. Method {@link #sum} (or, equivalently, {@link
 * #longValue}) returns the current total combined across the
 * variables maintaining the sum.
 *
 * 

This class is usually preferable to {@link AtomicLong} when * multiple threads update a common sum that is used for purposes such * as collecting statistics, not for fine-grained synchronization * control. Under low update contention, the two classes have similar * characteristics. But under high contention, expected throughput of * this class is significantly higher, at the expense of higher space * consumption. * *

LongAdders can be used with a {@link * java.util.concurrent.ConcurrentHashMap} to maintain a scalable * frequency map (a form of histogram or multiset). For example, to * add a count to a {@code ConcurrentHashMap freqs}, * initializing if not already present, you can use {@code * freqs.computeIfAbsent(k -> new LongAdder()).increment();} * *

This class extends {@link Number}, but does not define * methods such as {@code equals}, {@code hashCode} and {@code * compareTo} because instances are expected to be mutated, and so are * not useful as collection keys. * * @since 1.8 * @author Doug Lea */

4个抽象类
AtomicIntegerFieldUpdater

@since 1.5
/**
 * A reflection-based utility that enables atomic updates to
 * designated {@code volatile int} fields of designated classes.
 * This class is designed for use in atomic data structures in which
 * several fields of the same node are independently subject to atomic
 * updates.
 *
 * 

Note that the guarantees of the {@code 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 * {@code compareAndSet} and {@code set} on the same updater. * * @since 1.5 * @author Doug Lea * @param The type of the object holding the updatable field */

AtomicLongFieldUpdater

@since 1.5
/**
 * A reflection-based utility that enables atomic updates to
 * designated {@code volatile long} fields of designated classes.
 * This class is designed for use in atomic data structures in which
 * several fields of the same node are independently subject to atomic
 * updates.
 *
 * 

Note that the guarantees of the {@code 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 * {@code compareAndSet} and {@code set} on the same updater. * * @since 1.5 * @author Doug Lea * @param The type of the object holding the updatable field */

AtomicReferenceFieldUpdater

@since 1.5
/**
 * A reflection-based utility that enables atomic updates to
 * designated {@code volatile} reference fields of designated
 * classes.  This class is designed for use in atomic data structures
 * in which several reference fields of the same node are
 * independently subject to atomic updates. For example, a tree node
 * might be declared as
 *
 * 
 {@code
 * class Node {
 *   private volatile Node left, right;
 *
 *   private static final AtomicReferenceFieldUpdater leftUpdater =
 *     AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
 *   private static AtomicReferenceFieldUpdater rightUpdater =
 *     AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right");
 *
 *   Node getLeft() { return left; }
 *   boolean compareAndSetLeft(Node expect, Node update) {
 *     return leftUpdater.compareAndSet(this, expect, update);
 *   }
 *   // ... and so on
 * }}
* *

Note that the guarantees of the {@code 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 * {@code compareAndSet} and {@code set} on the same updater. * * @since 1.5 * @author Doug Lea * @param The type of the object holding the updatable field * @param The type of the field */

Striped64

1.8加入的
/**
 * A package-local class holding common representation and mechanics
 * for classes supporting dynamic striping on 64bit values. The class
 * extends Number so that concrete subclasses must publicly do so.
 */

总结

JDK1.5中:

原子性更新基本类型:
AtomicBoolean:原子更新布尔类型。
AtomicInteger:原子更新整型。
AtomicLong:原子更新长整型。

原子更新基本类型数组:

AtomicIntegerArray:原子更新整型数组里的元素。
AtomicLongArray:原子更新长整型数组里的元素。

更新字段:

抽象类:AtomicIntegerFieldUpdater: 原子更新整型字段的更新器。
抽象类:AtomicLongFieldUpdater: 原子更新长整型字段的更新器。
抽象类:AtomicReferenceFieldUpdater:原子更新引用类型里的字段。

更新引用类型:

AtomicReference:原子更新引用类型。

AtomicMarkableReference 原子更新带有标记位的引用类型

AtomicStampedReference:原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于原子的更数据和数据的版本号,可以解决使用CAS进行原子更新时,可能出现的ABA问题。

更新引用类型数组:
AtomicReferenceArray:原子更新引用类型数组里的元素。

JDK1.8中:

Striped64
JDK 8 的 java.util.concurrent.atomic 下有一个包本地的类 Striped64 ,它持有常见表示和机制用于类支持动态 striping 到 64bit 值上。

strping:
数据 striping 就是把逻辑上连续的数据分为多个段,使这一序列的段存储在不同的物理设备上。通过把段分散到多个设备上可以增加访问并发性,从而提升总体的吞吐量。

累加器:

DoubleAccumulator

DoubleAdder

LongAccumulator

LongAdder

1.8中的Double和Long累加器 将原本的

如Integer中

  do {
            prev = get();
            next = accumulatorFunction.applyAsInt(prev, x);
        } while (!compareAndSet(prev, next));

do while体系 变为

    public void add(long x) {
        Cell[] as; long b, v; int m; Cell a;
        if ((as = cells) != null || !casBase(b = base, b + x)) {
            boolean uncontended = true;
            if (as == null || (m = as.length - 1) < 0 ||
                (a = as[getProbe() & m]) == null ||
                !(uncontended = a.cas(v = a.value, v + x)))
                longAccumulate(x, null, uncontended);
        }
    }

参考:http://www.cnblogs.com/davidwang456/p/4670777.html

1.
在标量 如 boolean,integer,long,reference.
其底层是CAS (compare and swap) + volatile和native方法,从而避免了synchronized的高开销,执行效率大为提升

2.
AtomicIntegerArray,AtomicLongArray还有AtomicReferenceArray类进一步扩展了原子操作,对这些类型的数组提供了支持。这些类在为其数组元素提供 volatile 访问语义方面也引人注目,这对于普通数组来说是不受支持的。

他们内部并不是像AtomicInteger一样维持一个valatile变量,而是全部由native方法实现,如下
AtomicIntegerArray的实现片断

3.
AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater基于反射的实用工具,可以对指定类的指定 volatile 字段进行原子更新。API非常简单,但是也是有一些约束:

(1)字段必须是volatile类型的

(2)字段的描述类型(修饰符public/protected/default/private)是与调用者与操作对象字段的关系一致。也就是说 调用者能够直接操作对象字段,那么就可以反射进行原子操作。但是对于父类的字段,子类是不能直接操作的,尽管子类可以访问父类的字段。

(3)只能是实例变量,不能是类变量,也就是说不能加static关键字。

(4)只能是可修改变量,不能使final变量,因为final的语义就是不可修改。实际上final的语义和volatile是有冲突的,这两个关键字不能同时存在。

(5)对于AtomicIntegerFieldUpdater 和AtomicLongFieldUpdater 只能修改int/long类型的字段,不能修改其包装类型(Integer/Long)。如果要修改包装类型就需要使用AtomicReferenceFieldUpdater 。

netty5.0中类ChannelOutboundBuffer统计发送的字节总数,由于使用volatile变量已经不能满足,所以使用AtomicIntegerFieldUpdater 来实现的,看下面代码:

你可能感兴趣的:(JAVA)