在翻閱AQS(AbstractQueuedSynchronizer)類的過程當中,發現其進行原子操做的時候採用的是CAS。涉及的代碼以下:css
1: private static final Unsafe unsafe = Unsafe.getUnsafe();
2: private static final long stateOffset;
3: private static final long headOffset;
4: private static final long tailOffset;
5: private static final long waitStatusOffset;
6: private static final long nextOffset;
7:
8: static {
9: try {
10: stateOffset = unsafe.objectFieldOffset
11: (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
12: headOffset = unsafe.objectFieldOffset
13: (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
14: tailOffset = unsafe.objectFieldOffset
15: (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
16: waitStatusOffset = unsafe.objectFieldOffset
17: (Node.class.getDeclaredField("waitStatus"));
18: nextOffset = unsafe.objectFieldOffset
19: (Node.class.getDeclaredField("next"));
20:
21: } catch (Exception ex) { throw new Error(ex); }
22: }
23:
24: /**
25: * CAS head field. Used only by enq.
26: */
27: private final boolean compareAndSetHead(Node update) {
28: return unsafe.compareAndSwapObject(this, headOffset, null, update);
29: }
30:
31: /**
32: * CAS tail field. Used only by enq.
33: */
34: private final boolean compareAndSetTail(Node expect, Node update) {
35: return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
36: }
37:
38: /**
39: * CAS waitStatus field of a node.
40: */
41: private static final boolean compareAndSetWaitStatus(Node node,
42: int expect,
43: int update) {
44: return unsafe.compareAndSwapInt(node, waitStatusOffset,
45: expect, update);
46: }
47:
48: /**
49: * CAS next field of a node.
50: */
51: private static final boolean compareAndSetNext(Node node,
52: Node expect,
53: Node update) {
54: return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
55: }
能夠看到用到了compareAndSwapObject和compareAndSwapInt方法,那麼到底是怎麼用其來實現原子操做的呢?html
咱們以compareAndSwapObject方法爲例,其源碼大體以下:node
1: UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h))
2: UnsafeWrapper("Unsafe_CompareAndSwapObject");
3: oop x = JNIHandles::resolve(x_h); //待更新的新值,也就是UpdateValue
4: oop e = JNIHandles::resolve(e_h); //指望值,也就是ExpectValue
5: oop p = JNIHandles::resolve(obj); //待操做對象
6: HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset);//根據操做的對象和其在內存中的offset,計算出內存中具體位置
7: oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e, true);// 若是操做對象中的值和e指望值一致,則更新存儲值爲x,反之不更新
8: jboolean success = (res == e);
9: if (success) //知足更新條件
10: update_barrier_set((void*)addr, x); // 更新存儲值爲x
11: return success;
12: UNSAFE_END
從上述源碼能夠看到,compareAndSwapObject方法中的第一個參數和第二個參數,用於肯定待操做對象在內存中的具體位置的,而後取出值和第三個參數進行比較,若是相等,則將內存中的值更新爲第四個參數的值,同時返回true,代表原子更新操做完畢。反之則不更新內存中的值,同時返回false,代表原子操做失敗。app
一樣的,compareAndSwapInt方法也是類似的道理,第一個,第二個參數用來肯定當前操做對象在內存中的存儲值,而後和第三個expect value比較,若是相等,則將內存值更新爲第四個updaet value值。oop
因爲原始的方法使用比較麻煩,因此在AQS中進行了封裝,大大簡化了操做:this
1: private static final Unsafe unsafe = Unsafe.getUnsafe();
2: private static final long stateOffset;
3: private static final long headOffset;
4: private static final long tailOffset;
5: private static final long waitStatusOffset;
6: private static final long nextOffset;
7:
8: static {
9: try {
10: stateOffset = unsafe.objectFieldOffset
11: (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
12: headOffset = unsafe.objectFieldOffset
13: (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
14: tailOffset = unsafe.objectFieldOffset
15: (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
16: waitStatusOffset = unsafe.objectFieldOffset
17: (Node.class.getDeclaredField("waitStatus"));
18: nextOffset = unsafe.objectFieldOffset
19: (Node.class.getDeclaredField("next"));
20:
21: } catch (Exception ex) { throw new Error(ex); }
22: }
23:
24: /**
25: * CAS head field. Used only by enq.
26: */
27: private final boolean compareAndSetHead(Node update) {
28: return unsafe.compareAndSwapObject(this, headOffset, null, update);
29: }
30:
31: /**
32: * CAS tail field. Used only by enq.
33: */
34: private final boolean compareAndSetTail(Node expect, Node update) {
35: return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
36: }
37:
38: /**
39: * CAS waitStatus field of a node.
40: */
41: private static final boolean compareAndSetWaitStatus(Node node,
42: int expect,
43: int update) {
44: return unsafe.compareAndSwapInt(node, waitStatusOffset,
45: expect, update);
46: }
47:
48: /**
49: * CAS next field of a node.
50: */
51: private static final boolean compareAndSetNext(Node node,
52: Node expect,
53: Node update) {
54: return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
55: }
能夠在其餘項目中做爲小模塊進行引入並使用。這樣使用起來就很是方便了:atom
1:
2: /**
3: * Creates and enqueues node for current thread and given mode.
4: *
5: * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
6: * @return the new node
7: */
8: private Node addWaiter(Node mode) {
9: Node node = new Node(Thread.currentThread(), mode);
10: // Try the fast path of enq; backup to full enq on failure
11: Node pred = tail;
12: if (pred != null) {
13: node.prev = pred;
14: if (compareAndSetTail(pred, node)) {
15: pred.next = node;
16: return node;
17: }
18: }
19: enq(node);
20: return node;
21: }
參考文檔:spa
https://blog.csdn.net/qqqqq1993qqqqq/article/details/75211993.net