什么是原子类
java并法包中提供很多了几种原子类,如AtomicInteger、AtomicLong、AtomicReference等。原子类可以保证操作的不可分割,要么都操作完,要么都不操作。
以AtomicInteger为例讲解源码
主要成员变量:
private volatile long value;
操作的成员变量,包括对其获得与修改
这个成员变量被volatile修饰,说明原子类的实现是通过volatile关键字实现的,因为volatile保证了共享变量对其他线程的可见性
构造函数:
public AtomicLong(long initialValue) {
value = initialValue;
}
public AtomicLong() {
}
有两个构造函数,通过第一个构造函数我们可以指定vaule的初始化值,默认初始化值为0
get/set方法:
public final long get() {
return value;
}
public final void set(long newValue) {
value = newValue;
}
很简单的两个方法
compareAndSet(long expect, long update)方法:
public final boolean compareAndSet(long expect, long update) {
return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
这是原子性条件更新的条件。因为原子操作的时候,会检查值有没有发生变化,如果没有发生变化则跟新,但是如果有一个值原来是A,变成了B,后来又变成了A,它会检查不出变化,如果加上版本号则能比较出,A->B->A变成了1A->2B->3A。java原子类为解决这个问题,通过compareAndSet方法检查当前引用是否等于预期引用,当前标志是否等于预期标志,如果相等,则以院子的方式将该引用和该标识的值设置为给定的新值。compareAndSwapLong(this, valueOffset, expect, update)是一个本地方法。
addAndGet(long delta)方法:
public final long addAndGet(long delta) {
return unsafe.getAndAddLong(this, valueOffset, delta) + delta;
}
增加给定的值并且返回增加以后的值。这里面又有本地方法
小结:总之我觉得原子类之所以能保证原子操作是因为volitale这个关键字。平时我们一般很少用volitile,都是使用synchronized和lock。原子类相当于是对volitale做了一个封装。
注:原子类只有在特殊情况下才会使用,毕竟它只能保证一个变量的原子操作
一个简单的原子类测试类