从AutomicInteger开始
正式开始研究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)这些专门的操作了