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/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
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 newAtomicStampedReference
with the given initial values.- Parameters:
initialRef
- the initial referenceinitialStamp
- 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 isint[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 referencenewReference
- the new value for the referenceexpectedStamp
- the expected value of the stampnewStamp
- 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 referencenewReference
- the new value for the referenceexpectedStamp
- the expected value of the stampnewStamp
- 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 referencenewStamp
- 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 (returnfalse
) 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 referencenewStamp
- the new value for the stamp- Returns:
true
if successful
-
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 avolatile
variable.set
has the memory effects of writing (assigning) avolatile
variable.lazySet
has the memory effects of writing (assigning) avolatile
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 theweakCompareAndSet
.compareAndSet
and all other read-and-update operations such asgetAndIncrement
have the memory effects of both reading and writingvolatile
variables.
runtime\runtime2.go
ABA CAS