正式开始研究java.util.concurrent了,那最好就是从AtomicInteger开始咯

AtomicInterger, 类如其名,保证原子的更新value, 因此我们看到, 在它内部会维护一个value:

 1 public class AtomicInteger extends Number implements java.io.Serializable {
 2     private static final long serialVersionUID = 6214790243416807050L;
 3 
 4     // setup to use Unsafe.compareAndSwapInt for updates
 5     private static final Unsafe unsafe = Unsafe.getUnsafe();
 6     private static final long valueOffset;
 7 
 8     static {
 9       try {
10         valueOffset = unsafe.objectFieldOffset
11             (AtomicInteger.class.getDeclaredField("value"));
12       } catch (Exception ex) { throw new Error(ex); }
13     }
14 
15     private volatile int value;
16 
17     // blahblah...
18 }

值得注意的是,这个value使用volatile来修饰, 兹以为,AtomicInteger只保证原子性,并不保证内存一致性,也就是不保证happens-before原则, 而在多线程中,保证数据一致性是很重要的一条,所以需要volatile来干这件事(happens-before)

来看看它是怎么原子操作的:

 1 /**
 2      * Atomically sets to the given value and returns the old value.
 3      *
 4      * @param newValue the new value
 5      * @return the previous value
 6      */
 7     public final int getAndSet(int newValue) {
 8         for (;;) {
 9             int current = get();
10             if (compareAndSet(current, newValue))
11                 return current;
12         }
13     }
14 
15 
16     /**
17      * Gets the current value.
18      *
19      * @return the current value
20      */
21     public final int get() {
22         return value;
23     }

看起来很简单啊,就是一个for循环,不断的调用compareAndSet来设置newValue

 1 /**
 2      * Atomically sets the value to the given updated value
 3      * if the current value {@code ==} the expected value.
 4      *
 5      * @param expect the expected value
 6      * @param update the new value
 7      * @return true if successful. False return indicates that
 8      * the actual value was not equal to the expected value.
 9      */
10     public final boolean compareAndSet(int expect, int update) {
11         return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
12     }

这就是大名鼎鼎的CAS了, 调用的是unsafe的native实现,是一种特定的指令,它会原子性的尝试设置一个newValue,但是只有在原值等于expect的时候才会成功具体的CAS详细介绍可以参照wiki
我们清楚了, 它是通过CAS,不断的for循环尝试,如果别的线程在它get()和CAS之间改变了这个值,那将会导致CAS失败,因此会进入下一轮循环,知道当前线程成功更新为新值,这就保证了操作的原子性

最后,也就不难理解为什么还要留出incrementAndGet()、decrementAndGet()、addAndGet(int delta)、getAndAdd(int delta)这些专门的操作了