AtomicInteger
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