|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AtomicStampedReference | Line # 20 | 16 | 11 | 96.3% |
0.962963
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AtomicStampedReference.ReferenceIntegerPair | Line # 22 | 2 | 1 | 100% |
1.0
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (7) | |||
| Result | |||
|
0.6666667
|
AtomicStampedReferenceTest.testGetSet
AtomicStampedReferenceTest.testGetSet
|
1 PASS | |
|
0.53333336
|
AtomicStampedReferenceTest.testCompareAndSet
AtomicStampedReferenceTest.testCompareAndSet
|
1 PASS | |
|
0.53333336
|
AtomicStampedReferenceTest.testAttemptStamp
AtomicStampedReferenceTest.testAttemptStamp
|
1 PASS | |
|
0.53333336
|
AtomicStampedReferenceTest.testWeakCompareAndSet
AtomicStampedReferenceTest.testWeakCompareAndSet
|
1 PASS | |
|
0.46666667
|
AtomicStampedReferenceTest.testCompareAndSetInMultipleThreads
AtomicStampedReferenceTest.testCompareAndSetInMultipleThreads
|
1 PASS | |
|
0.46666667
|
AtomicStampedReferenceTest.testCompareAndSetInMultipleThreads2
AtomicStampedReferenceTest.testCompareAndSetInMultipleThreads2
|
1 PASS | |
|
0.36666667
|
AtomicStampedReferenceTest.testConstructor
AtomicStampedReferenceTest.testConstructor
|
1 PASS | |
| 1 | /* | |
| 2 | * Written by Doug Lea with assistance from members of JCP JSR-166 | |
| 3 | * Expert Group and released to the public domain, as explained at | |
| 4 | * http://creativecommons.org/licenses/publicdomain | |
| 5 | */ | |
| 6 | ||
| 7 | package edu.emory.mathcs.backport.java.util.concurrent.atomic; | |
| 8 | ||
| 9 | /** | |
| 10 | * An {@code AtomicStampedReference} maintains an object reference | |
| 11 | * along with an integer "stamp", that can be updated atomically. | |
| 12 | * | |
| 13 | * <p> Implementation note. This implementation maintains stamped | |
| 14 | * references by creating internal objects representing "boxed" | |
| 15 | * [reference, integer] pairs. | |
| 16 | * | |
| 17 | * @since 1.5 | |
| 18 | * @author Doug Lea | |
| 19 | */ | |
| 20 | public class AtomicStampedReference { | |
| 21 | ||
| 22 | private static class ReferenceIntegerPair { | |
| 23 | private final Object reference; | |
| 24 | private final int integer; | |
| 25 | 19 |
ReferenceIntegerPair(Object r, int i) { |
| 26 | 19 | reference = r; integer = i; |
| 27 | } | |
| 28 | } | |
| 29 | ||
| 30 | private final AtomicReference atomicRef; | |
| 31 | ||
| 32 | /** | |
| 33 | * Creates a new {@code AtomicStampedReference} with the given | |
| 34 | * initial values. | |
| 35 | * | |
| 36 | * @param initialRef the initial reference | |
| 37 | * @param initialStamp the initial stamp | |
| 38 | */ | |
| 39 | 8 |
public AtomicStampedReference(Object initialRef, int initialStamp) { |
| 40 | 8 | atomicRef = new AtomicReference( |
| 41 | new ReferenceIntegerPair(initialRef, initialStamp)); | |
| 42 | } | |
| 43 | ||
| 44 | /** | |
| 45 | * Returns the current value of the reference. | |
| 46 | * | |
| 47 | * @return the current value of the reference | |
| 48 | */ | |
| 49 | 7 |
public Object getReference() { |
| 50 | 7 | return getPair().reference; |
| 51 | } | |
| 52 | ||
| 53 | /** | |
| 54 | * Returns the current value of the stamp. | |
| 55 | * | |
| 56 | * @return the current value of the stamp | |
| 57 | */ | |
| 58 | 11 |
public int getStamp() { |
| 59 | 11 | return getPair().integer; |
| 60 | } | |
| 61 | ||
| 62 | /** | |
| 63 | * Returns the current values of both the reference and the stamp. | |
| 64 | * Typical usage is {@code int[1] holder; ref = v.get(holder); }. | |
| 65 | * | |
| 66 | * @param stampHolder an array of size of at least one. On return, | |
| 67 | * {@code stampholder[0]} will hold the value of the stamp. | |
| 68 | * @return the current value of the reference | |
| 69 | */ | |
| 70 | 11 |
public Object get(int[] stampHolder) { |
| 71 | 11 | ReferenceIntegerPair p = getPair(); |
| 72 | 11 | stampHolder[0] = p.integer; |
| 73 | 11 | return p.reference; |
| 74 | } | |
| 75 | ||
| 76 | /** | |
| 77 | * Atomically sets the value of both the reference and stamp | |
| 78 | * to the given update values if the | |
| 79 | * current reference is {@code ==} to the expected reference | |
| 80 | * and the current stamp is equal to the expected stamp. | |
| 81 | * | |
| 82 | * <p>May <a href="package-summary.html#Spurious">fail spuriously</a> | |
| 83 | * and does not provide ordering guarantees, so is only rarely an | |
| 84 | * appropriate alternative to {@code compareAndSet}. | |
| 85 | * | |
| 86 | * @param expectedReference the expected value of the reference | |
| 87 | * @param newReference the new value for the reference | |
| 88 | * @param expectedStamp the expected value of the stamp | |
| 89 | * @param newStamp the new value for the stamp | |
| 90 | * @return true if successful | |
| 91 | */ | |
| 92 | 2 |
public boolean weakCompareAndSet(Object expectedReference, |
| 93 | Object newReference, | |
| 94 | int expectedStamp, | |
| 95 | int newStamp) { | |
| 96 | 2 | ReferenceIntegerPair current = getPair(); |
| 97 | 2 | return expectedReference == current.reference && |
| 98 | expectedStamp == current.integer && | |
| 99 | ((newReference == current.reference && | |
| 100 | newStamp == current.integer) || | |
| 101 | atomicRef.weakCompareAndSet(current, | |
| 102 | new ReferenceIntegerPair(newReference, | |
| 103 | newStamp))); | |
| 104 | } | |
| 105 | ||
| 106 | /** | |
| 107 | * Atomically sets the value of both the reference and stamp | |
| 108 | * to the given update values if the | |
| 109 | * current reference is {@code ==} to the expected reference | |
| 110 | * and the current stamp is equal to the expected stamp. | |
| 111 | * | |
| 112 | * @param expectedReference the expected value of the reference | |
| 113 | * @param newReference the new value for the reference | |
| 114 | * @param expectedStamp the expected value of the stamp | |
| 115 | * @param newStamp the new value for the stamp | |
| 116 | * @return true if successful | |
| 117 | */ | |
| 118 | 7 |
public boolean compareAndSet(Object expectedReference, |
| 119 | Object newReference, | |
| 120 | int expectedStamp, | |
| 121 | int newStamp) { | |
| 122 | 7 | ReferenceIntegerPair current = getPair(); |
| 123 | 7 | return expectedReference == current.reference && |
| 124 | expectedStamp == current.integer && | |
| 125 | ((newReference == current.reference && | |
| 126 | newStamp == current.integer) || | |
| 127 | atomicRef.compareAndSet(current, | |
| 128 | new ReferenceIntegerPair(newReference, | |
| 129 | newStamp))); | |
| 130 | } | |
| 131 | ||
| 132 | ||
| 133 | /** | |
| 134 | * Unconditionally sets the value of both the reference and stamp. | |
| 135 | * | |
| 136 | * @param newReference the new value for the reference | |
| 137 | * @param newStamp the new value for the stamp | |
| 138 | */ | |
| 139 | 2 |
public void set(Object newReference, int newStamp) { |
| 140 | 2 | ReferenceIntegerPair current = getPair(); |
| 141 | 2 | if (newReference != current.reference || newStamp != current.integer) |
| 142 | 2 | atomicRef.set(new ReferenceIntegerPair(newReference, newStamp)); |
| 143 | } | |
| 144 | ||
| 145 | /** | |
| 146 | * Atomically sets the value of the stamp to the given update value | |
| 147 | * if the current reference is {@code ==} to the expected | |
| 148 | * reference. Any given invocation of this operation may fail | |
| 149 | * (return {@code false}) spuriously, but repeated invocation | |
| 150 | * when the current value holds the expected value and no other | |
| 151 | * thread is also attempting to set the value will eventually | |
| 152 | * succeed. | |
| 153 | * | |
| 154 | * @param expectedReference the expected value of the reference | |
| 155 | * @param newStamp the new value for the stamp | |
| 156 | * @return true if successful | |
| 157 | */ | |
| 158 | 1 |
public boolean attemptStamp(Object expectedReference, int newStamp) { |
| 159 | 1 | ReferenceIntegerPair current = getPair(); |
| 160 | ||