下面列出了java.util.concurrent.atomic.AtomicReferenceArray#getAndSet() 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public void offer(@NotNull ByteBuf buf) {
long pos1, pos2;
do {
pos1 = pos.get();
pos2 = pos1 + 0x100000000L;
} while (!pos.compareAndSet(pos1, pos2));
int head = (int) (pos2 >>> 32);
buf.pos = head;
AtomicReferenceArray<ByteBuf> bufs = array.get();
int idx = head & (bufs.length() - 1);
ByteBuf buf2 = bufs.getAndSet(idx, buf);
if (buf2 == null && bufs == array.get()) {
return; // fast path, everything is fine
}
// otherwise, evict bufs into map to make it retrievable by corresponding pop()
pushToMap(bufs, idx, buf2);
}
@Override
public synchronized V put(int key, V value) {
checkNotNull(value, "Null value");
AtomicReferenceArray<V> values = this.values;
if (key < 0) {
throw new IllegalArgumentException(negativeKey(key));
} else if (key >= values.length()) {
expandAndPut(key, value); // Put in a separate method for inlining (its a unlikely slow-case)
return null;
} else {
V oldValue = values.getAndSet(key, value);
if (oldValue == null) SIZE_UPDATER.incrementAndGet(this); // New entry
return oldValue;
}
}
@Override
public synchronized V remove(int key) {
AtomicReferenceArray<V> values = this.values;
if (key < 0) {
throw new IllegalArgumentException(negativeKey(key));
} else if (key >= values.length()) {
return null;
} else {
V oldValue = values.getAndSet(key, null);
if (oldValue != null)
SIZE_UPDATER.decrementAndGet(this); // Entry was there before, but now we're removing it
return oldValue;
}
}
public static void main(String[] args) {
AtomicReferenceArray<Integer> x = new AtomicReferenceArray(128);
Integer y = new Integer(0);
for (int i = 0; i < 50000; i++) {
x.getAndSet(i % x.length(), y);
}
}
public static void main(String[] args) {
AtomicReferenceArray a = new AtomicReferenceArray(10000);
for (int i = 0; i < 100000; i++) {
a.getAndSet(9999, new Object());
if (i > 99990) System.gc();
}
}
@Override
public final T takeAndClear(long ptr)
{
final AtomicReferenceArray<T> ring = _ring;
final int index = getIndex(ptr);
T value;
while ((value = ring.getAndSet(index, null)) == null) {
}
return value;
}
@Nullable
public ByteBuf poll() {
long pos1, pos2;
int head, tail;
do {
pos1 = pos.get();
head = (int) (pos1 >>> 32);
tail = (int) pos1;
if (head == tail) {
return null;
}
tail++;
if (ByteBufPool.USE_WATCHDOG) {
int size = head - tail;
realMin.updateAndGet(prevMin -> Math.min(prevMin, size));
}
pos2 = ((long) head << 32) + (tail & 0xFFFFFFFFL);
} while (!pos.compareAndSet(pos1, pos2));
Integer boxedTail = null;
while (true) {
AtomicReferenceArray<ByteBuf> bufs = array.get();
ByteBuf buf = bufs.getAndSet(tail & (bufs.length() - 1), null);
if (buf == null) {
if (boxedTail == null) {
boxedTail = tail;
}
buf = map.remove(boxedTail);
if (buf == null) {
Thread.yield();
continue;
}
}
if (buf.pos == tail) {
return buf;
}
map.put(buf.pos, buf);
}
}
private void pushToMap(AtomicReferenceArray<ByteBuf> bufs, int idx, @Nullable ByteBuf buf2) {
ByteBuf buf3 = bufs.getAndSet(idx, null); // bufs may be stale at this moment, evict the data from this cell
if (buf2 == null && buf3 == null) return;
if (buf2 != null) map.put(buf2.pos, buf2);
if (buf3 != null) map.put(buf3.pos, buf3);
ensureCapacity(); // resize if needed
}
private void resize(int capacityNew) {
AtomicReferenceArray<ByteBuf> bufsNew = new AtomicReferenceArray<>(capacityNew);
AtomicReferenceArray<ByteBuf> bufsOld = array.getAndSet(bufsNew);
// evict everything from old bufs array
for (int i = 0; i < bufsOld.length(); i++) {
ByteBuf buf = bufsOld.getAndSet(i, null);
if (buf != null) map.put(buf.pos, buf);
}
}