1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
public final class AtomicFieldUpdater {
private static final AtomicReferenceFieldUpdater<AtomicFieldUpdater, Value[]> VALUE_UPDATER = AtomicReferenceFieldUpdater.newUpdater(AtomicFieldUpdater.class, Value[].class, "values"); private volatile Value[] values = new Value[]{new Value()};
private void addValues(AtomicFieldUpdater hold, AtomicReferenceFieldUpdater<AtomicFieldUpdater, Value[]> updater, long initVaule, Value... valuesToAdd) {
Value[] currentValues; Value[] updateValues; do {
currentValues = updater.get(hold); updateValues = copyOf(currentValues, currentValues.length + valuesToAdd.length);
int index = currentValues.length; for (Value value : valuesToAdd) { value.value = initVaule; updateValues[index++] = value; }
} while (!updater.compareAndSet(hold, currentValues, updateValues));
}
private boolean removeValues(AtomicFieldUpdater hold, AtomicReferenceFieldUpdater<AtomicFieldUpdater, Value[]> updater, Value valuesToRemove) { int numToRemove; Value[] oldValues; Value[] newValues; do {
oldValues = updater.get(hold);
numToRemove = countMatching(oldValues, valuesToRemove);
if (0 == numToRemove) { break; }
final int oldSize = oldValues.length; newValues = new Value[oldSize - numToRemove]; for (int i = 0,pos = 0; i < oldSize; i++) { Value testValue = oldValues[i]; if (valuesToRemove != testValue){ newValues[pos++] = testValue; } }
} while (!updater.compareAndSet(hold, oldValues, newValues));
return numToRemove != 0; }
private static int countMatching(Value[] values,Value toMatch){ int numToRemove = 0; for (Value value : values) { if (value==toMatch){ numToRemove++; } } return numToRemove; }
static class Value { volatile long value = 1L; }
public static void main(String[] args) { AtomicFieldUpdater atomicFieldUpdater = new AtomicFieldUpdater();
Value value = new Value(); atomicFieldUpdater.addValues(atomicFieldUpdater, AtomicFieldUpdater.VALUE_UPDATER, 10, value);
System.out.println();
atomicFieldUpdater.removeValues(atomicFieldUpdater,AtomicFieldUpdater.VALUE_UPDATER,value);
System.out.println(); } }
|