1、开始
public class AtomicInteger extends Number implements java.io.Serializable
继承了类Number,实现了接口Serializable(可序列化)
2、属性
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
//用来记录value本身在内存中的内存地址,这个记录,也主要是为了在更新操作在内存中找到value的位置,方便比较。
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
//用来存储当前的值,声明为volatile,是为了保证在更新操作时,当前线程可以拿到value的最新的值(并发情况下,value可能已经被其他线程更新了)
private volatile int value;
3、构造器
public AtomicInteger(int initialValue) {
value = initialValue;
}
public AtomicInteger() {
}
4、方法
public final int get() {
return value;
}
public final void set(int newValue) {
value = newValue;
}
public final int getAndSet(int newValue) {
for (;;) {
//获取在当前线程中的值
int current = get();
if (compareAndSet(current, newValue))
return current;
}
}
public final boolean compareAndSet(int expect, int update) {
//使用unsafe的本地方法,实现高效的硬件级别CAS
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
public final boolean weakCompareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
5、注意
1)、CAS是Compare and Swap的意思,比较并交换。CAS是乐观锁技术,是一个非阻塞的算法,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能够更新成功,而其他的线程都会失败,失败的线程并不会被挂起,而是被告知此次竞争失败,并可以再次尝试。CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B,当且仅当预期值A和内存值V相等时,将内存值V修改为B,否则什么都不做。
2)、CAS操作中,会出现ABA问题。由于CAS需要在操作的时候检查下值是否发生了变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,最后又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化,但是实际上却发生了变化。ABA问题的解决思路就是使用版本号,在变量前面追加上版本号,每次变量更新的时候把版本号加1,那么A-B-A,就会变成1A-2B-3C。
ABA问题:若其中一个线程修改A-B-A,另外一个线程仍然读取到A,虽然值是预期值,但并不能说明该内存值没有变化。
可以使用AtomicStampedReference解决ABA问题,使之执行CAS失败
参考资料:
http://my.oschina.net/magicly007/blog/364102
http://www.importnew.com/20472.html