ABA 多线程 AtomicStampedReference 并发 原子 CAS

 小结:

1、An AtomicStampedReference maintains an object reference along with an integer "stamp", that can be updated atomically.

给每一个对象的引用追加一个可以被原子更新的戳。

 

 

 

 

什么是ABA问题? - 知乎 https://www.zhihu.com/question/23281499

1)

2)小明账户上有100元。现在小明取钱,小强汇钱,诈骗分子盗刷三个动作同时进行。

1,小明取50元。

2,诈骗分子盗刷50元。

3,小强给小明汇款50元。

此时,银行交易系统出问题,每笔交易无法通过短信告知小明。ABA问题就是:

1,小明验证账户上有100元后,取出50元。——账上有50元。

2,小强不会验证小明账户的余额,直接汇款50元。——账上有100元。

3,诈骗分子验证账户有100元后,取出50元。——账上有50元。

小强没有告诉小明自己汇钱,小明也没收到短信,那么小明就一直以为只有自己取款操作,最后损失了50元。

https://www.zhihu.com/question/23281499/answer/729694164

3)
In multithreadedcomputing, theABA problemoccurs during synchronization, when a location is read twice, has the same value for both reads, and "value is the same" is used to indicate "nothing has changed". However, another thread can execute between the two reads and change the value, do other work, then change the value back, thus fooling the first thread into thinking "nothing has changed" even though the second thread did work that violates that assumption.


https://www.zhihu.com/question/23281499/answer/1029690466
 

AtomicStampedReference (Java Platform SE 8 ) https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicStampedReference.html
public class AtomicStampedReference<V>
extends Object
An AtomicStampedReference maintains an object reference along with an integer "stamp", that can be updated atomically.

Implementation note: This implementation maintains stamped references by creating internal objects representing "boxed" [reference, integer] pairs.

 

  • Constructor Detail

    • AtomicStampedReference

      public AtomicStampedReference(V initialRef,
                                    int initialStamp)
      Creates a new AtomicStampedReference with the given initial values.
      Parameters:
      initialRef - the initial reference
      initialStamp - the initial stamp
  • Method Detail

    • getReference

      public V getReference()
      Returns the current value of the reference.
      Returns:
      the current value of the reference
    • getStamp

      public int getStamp()
      Returns the current value of the stamp.
      Returns:
      the current value of the stamp
    • get

      public V get(int[] stampHolder)
      Returns the current values of both the reference and the stamp. Typical usage is int[1] holder; ref = v.get(holder); .
      Parameters:
      stampHolder - an array of size of at least one. On return, stampholder[0] will hold the value of the stamp.
      Returns:
      the current value of the reference
    • weakCompareAndSet

      public boolean weakCompareAndSet(V expectedReference,
                                       V newReference,
                                       int expectedStamp,
                                       int newStamp)
      Atomically sets the value of both the reference and stamp to the given update values if the current reference is == to the expected reference and the current stamp is equal to the expected stamp.

      May fail spuriously and does not provide ordering guarantees, so is only rarely an appropriate alternative to compareAndSet.

      Parameters:
      expectedReference - the expected value of the reference
      newReference - the new value for the reference
      expectedStamp - the expected value of the stamp
      newStamp - the new value for the stamp
      Returns:
      true if successful
    • compareAndSet

      public boolean compareAndSet(V expectedReference,
                                   V newReference,
                                   int expectedStamp,
                                   int newStamp)
      Atomically sets the value of both the reference and stamp to the given update values if the current reference is == to the expected reference and the current stamp is equal to the expected stamp.
      Parameters:
      expectedReference - the expected value of the reference
      newReference - the new value for the reference
      expectedStamp - the expected value of the stamp
      newStamp - the new value for the stamp
      Returns:
      true if successful
    • set

      public void set(V newReference,
                      int newStamp)
      Unconditionally sets the value of both the reference and stamp.
      Parameters:
      newReference - the new value for the reference
      newStamp - the new value for the stamp
    • attemptStamp

      public boolean attemptStamp(V expectedReference,
                                  int newStamp)
      Atomically sets the value of the stamp to the given update value if the current reference is == to the expected reference. Any given invocation of this operation may fail (return false) spuriously, but repeated invocation when the current value holds the expected value and no other thread is also attempting to set the value will eventually succeed.
      Parameters:
      expectedReference - the expected value of the reference
      newStamp - the new value for the stamp
      Returns:
      true if successful
 
java.util.concurrent.atomic (Java Platform SE 8 ) https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html#weakCompareAndSet
 

The memory effects for accesses and updates of atomics generally follow the rules for volatiles, as stated in The Java Language Specification (17.4 Memory Model):

  • get has the memory effects of reading a volatile variable.
  • set has the memory effects of writing (assigning) a volatile variable.
  • lazySet has the memory effects of writing (assigning) a volatile variable except that it permits reorderings with subsequent (but not previous) memory actions that do not themselves impose reordering constraints with ordinary non-volatile writes. Among other usage contexts, lazySet may apply when nulling out, for the sake of garbage collection, a reference that is never accessed again.
  • weakCompareAndSet atomically reads and conditionally writes a variable but does not create any happens-before orderings, so provides no guarantees with respect to previous or subsequent reads and writes of any variables other than the target of the weakCompareAndSet.
  • compareAndSet and all other read-and-update operations such as getAndIncrement have the memory effects of both reading and writing volatile variables.


runtime\runtime2.go

ABA CAS

    // _Psyscall means a P is not running user code. It has
    // affinity to an M in a syscall but is not owned by it and
    // may be stolen by another M. This is similar to _Pidle but
    // uses lightweight transitions and maintains M affinity.
    //
    // Leaving _Psyscall must be done with a CAS, either to steal
    // or retake the P. Note that there's an ABA hazard: even if
    // an M successfully CASes its original P back to _Prunning
    // after a syscall, it must understand the P may have been
    // used by another M in the interim.
    _Psyscall

 

 

 

 

 

 

 

 

 

 
posted @ 2017-04-06 14:49  papering  阅读(184)  评论(0编辑  收藏  举报