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
AtomicInteger
@since 1.5
However, this class does extend
{@code Number} to allow uniform access by tools and utilities that
deal with
AtomicIntegerArray
AtomicLong
@since 1.5
特点:
自己翻译: 一、可能以原子方式更新。
二、不能当作Long的替代品
三、类继承自Number,允许被以数值为基础的 classes文件 当做工具类去使用
AtomicLongArray
AtomicMarkableReference
@since 1.5
/**
* An {@code AtomicMarkableReference} maintains an object reference
* along with a mark bit, that can be updated atomically.
*
* <p>Implementation note: This implementation maintains markable
* references by creating internal objects representing "boxed"
* [reference, boolean] pairs.
*
* @since 1.5
* @author Doug Lea
* @param
AtomicReference
AtomicReferenceArray
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.
*
* <p>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.
*
* <p>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.
*
* <p>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)}.
*
* <p>This class extends {@link Number}, but does <em>not</em> 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.
*
* <p>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.
*
* <p>This class extends {@link Number}, but does <em>not</em> 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})将当前的总数组合在维持总和的变量上。在线程内部或跨线程中积累的顺序没有保证。因此,如果需要数值稳定性,这个类可能不适用,特别是当组合了大量不同数量级的值时。
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.
*
* <p>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.
*
* <p>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.
*
* <p>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}.
*
* <p>This class extends {@link Number}, but does <em>not</em> 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
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.
*
* <p>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.
*
* <p>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<String,LongAdder> freqs},
* initializing if not already present, you can use {@code
* freqs.computeIfAbsent(k -> new LongAdder()).increment();}
*
* <p>This class extends {@link Number}, but does <em>not</em> 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
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.
*
* <p>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 <T> The type of the object holding the
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.
*
* <p>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 <T> The type of the object holding the
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
*
* <pre> {@code
* class Node {
* private volatile Node left, right;
*
* private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater =
* AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
* private static AtomicReferenceFieldUpdater<Node, Node> 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
* }}</pre>
*
* <p>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 <T> The type of the object holding the updatable field
* @param <V> 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);
}
}
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 来实现的,看下面代码: