美文网首页
Java8 API学习27 - java.util.concur

Java8 API学习27 - java.util.concur

作者: raBBtt | 来源:发表于2018-07-11 18:41 被阅读0次

AtomicInteger

public class AtomicInteger extends Number implements java.io.Serializable

AtomicInteger提供了对整数的原子性操作(例如i++), 每个类中有一个成员变量value存储该整数值.

AtomicInteger的对象方法

  1. 构造方法
AtomicInteger()
AtomicInteger(int)
  1. 对象方法
    注意一些方法的顺序, 是先运算再获取值, 还是先获取值再运算
/* 根据传入的x和函数进行操作, func有2个参数, 原value和传入的x,
例: f(x, (value, x0) -> value * x0) = value * x; 由于java语法原因x0还不能写作x.
怎么感觉这么别扭呢*/
final int accumulateAndGet(int x, IntBinaryOperator func)
final int getAndAccumulate(int x, IntBinaryOperator func) //注意顺序

//加法
final int addAndGet(int delta)
final int getAndAdd(int delta)

final int decrementAndGet() //--i
final int IncrementAndGet() //++i
final int getAndDecrement()
final int getAndIncrement()

//如果value等于expect, 那么更新为update
final boolean compareAndSet(int expect, int update)
//* 文档说这个方法可能会失败...那该什么时候用呢?
final boolean weakCompareAndSet(int expect, int update)

int get()
final void set(int)
final void lazySet(int) //不保证修改立即生效; 可以一定程度上提高性能?
final int getAndSet(int)

final int updateAndGet(IntUnaryOperator)
final int getAndUpdate(IntUnaryOperator)
  1. 类型转换, 继承于Number, 如intValue()等, 请参考Number类, 此处略.

AtomicInteger中的函数式方法

int accumulateAndGet(int x, (value, x0) -> value * x0);
int updateAndGet(value -> value * value);

这样一比较可以看到accumulateAndGetupdateAndGet的增强, 因为java语法中本地变量是不能直接传入lambda表达式的. 参考"Local variable x defined in an enclosing scope must be final or effectively final".

类似的AtomicXxx类

类似的类还有AtomicBooleanAtomicLong, 其中前者的方法相对少一些, 后者的方法和AtomicInteger相同.
此外还有一个AtomicReference<V>, 这个类是在泛型V上做原子性操作. 不难理解, 和AtomicInteger相比这个类没有加减法相关的方法, 而其他方法比如比较, 更新和读取等则保留了下来.
这个类又衍生出了AtomicStampedReference, 加上了一个时间戳/版本号一样的标记, 具体为了解决哪些问题, 请参考其他人的文章吧.

AtomicIntegerArray

public class AtomicIntegerArray implements java.io.Serializable

和AtomicInteger相比, 这个类是对一个int数组的原子性操作.
注意, 这个类代表了一个固定长度的数组, 而不是list.

AtomicIntegerArray的构造方法

AtomicIntegerArray(int length) //创建空数组, 长为length, 默认值为0
AtomicIntegerArray(int[] array) //复制传入的数组

AtomicIntegerArray的对象方法

实际上, 这个类的方法只是在AtomicInteger的基础上多加了一个参数, 即下标, 其他方面都是相同的, 如addAndGet(int delta)变为了addAndGet(int i, int delta)等. 因此这里略去.

类似的类

还有AtomicLongArrayAtomicReferenceArray

atomic包中的其他类

atomic包中还有一个AtomicIntegerFieldUpdater<T>及类似命名的类, 简单地说, 这个类可以通过反射对以个类中的某个int型变量做原子性操作. 考虑到和反射有关, 也许以后有机会能再讲到吧.

LongAccumulator

public class LongAccumulator extends Striped64 implements Serializable

其中Striped64是一个非public的抽象类

abstract class Striped64 extends Number

对于Striped64 文档的介绍是"A package-local class holding common representation and mechanics for classes supporting dynamic striping on 64bit values", 我们应该没有必要关心这个类.
回到正文. LongAccumulator是java8才新增的类, 根据文档的说法, 这个类在并发较高的情况下比AtomicLong又更好的性能表现, 这个类在部分情况下可以代替AtomicLong.

LongAccumulator的构造方法

public LongAccumulator(LongBinaryOperator op, long identity)

这个构造方法看起来比较少见啊... 它的含义是确定了一个操作方法和初始值identity, 当调用accumulate方法更新identity的时候只能使用该方法对其进行操作, 所以这个类起名叫Accumulator. LongBinaryOperator需要传入2个参数, 参数1代表原value, 参数2则代表accumulate方法需要传入的参数, 例如LongAccumulator((a, b) -> a - b, 100), 表示初始值为100, 每次调用accumulate方法会减去b.

LongAccumulator的对象方法

  1. 一般方法
void accumulate(long) //累加, 即更新操作
long get()
void reset() //重设为初始值
long getThenReset() //获取当前值, 然后重设为初始值, 把上述两步合为一个原子性操作
  1. 从Number类继承的方法, 如intValue等, 略

LongAdder

public class LongAdder extends Striped64 implements Serializable

LongAdder只能做普通的加减法, 可以看做是LongAccumulator的一种特例

LongAdder的方法

  1. 构造方法和一般方法
LongAdder() //只有这一个构造方法, 初始值为0

void add(long)
void decrement()
void increment()
void reset() //重置为0
long sum() //求和并返回结果, 类似于LongAccumulator的get()方法
long sumThenReset() //求和并重置为0
  1. 从Number类继承的方法, 如intValue等, 略.
    为什么这里求和的方法叫做sum而不是get呢? 简单来说为了在原子性操作的同时提高效率, LongAdder内部并非只有一个value值而是有一个数组存储数值(数组是和线程对应的吗? 我不知道, 请参考其他文章或源码), 而需要计算结果的时候才会把数组中的值相加.

其他类似的类

DoubleAccumulatorDoubleAdder.

相关文章

网友评论

      本文标题:Java8 API学习27 - java.util.concur

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