Java并发编程里不得不提java提供的高并发工具包,JUC包提供丰富的并发编程工具类,因此学习Java并发编程,JUC包就是学习的基础。在学习JUC包之前,我们先了解一下JUC的基本功能模块.
JUC并发包的基本结构体系
atomic包:基于CAS策略的的原子类包。
locks包:是基于AQS的抽象队列的同步框架,提供并发编程的同步锁。
并发容器:提供高并发条件下的数据存储。
并发计算框架:提供多线程执行框架。
并发工具:实现上述框架的工具类。
AtomicInteger的实现原理
AtomicInteger采用基于CAS进行数据的原子性操作的Unsafe工具类,Unsafe类通过在对象实例化的时候记录数据的地址,并通过比较获取的原有数据与新获取数据是否一致来确定数据是否被其他线程修改,从而进行相关的数据操作。而对于数据的可见性,AtomicInteger采用volatile关键字进行修饰,使得线程对数据的操作均作用于主存,从而保证数据在多线程之间的可见性。AtomicInteger的初始化如下所示。
代码语言:javascript复制 //java操作内存的工具类,采用CAS能够操作内存。
private static final Unsafe unsafe = Unsafe.getUnsafe();
//数据在内存中偏移量
private static final long valueOffset;
static {
try {
//在对象进行实例化的时候将值得内存偏移地址设置到程序中。
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
//采用Volatile关键字来管理数据,volatile提供数据的可见性。
//volatile底层采用汇编指令load,cpu直接通过操作主存来控制所修饰的数据。
private volatile int value;
AtomicInteger提供的主要接口
AtomicInteger提供基本的数据操作,对于复杂的数据操作,其提供了lambda 表达式进行支持。我们只需将必要的逻辑写到lambda中即可。以下是AtomicInteger提供的主要接口。
代码语言:javascript复制
//先获取值,然后进行赋值
public final int getAndSet(int newValue);
//时候用CAS进行判断原数据是否被其他线程修改了
//如果被修改了则返回false,否则进行数据更新
public final boolean compareAndSet(int expect, int update);
//先获取,再进行加一赋值
public final int getAndIncrement();
//先获取,再进行减一赋值
public final int getAndDecrement();
//先获取,再进行加法赋值
public final int getAndAdd(int delta);
//先加一,再获取值
public final int incrementAndGet();
//先减一,再获取值
public final int decrementAndGet();
//添加再获取
public final int addAndGet(int delta);
//采用CAS进行赋值
public final int getAndUpdate(IntUnaryOperator updateFunction);
//更新赋值
public final int updateAndGet(IntUnaryOperator updateFunction);
//获取之后,进行复杂的数值操作
public final int getAndAccumulate(int x,
IntBinaryOperator accumulatorFunction);