下面列出了java.lang.invoke.VarHandle#releaseFence ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Initializes or doubles the capacity of array. Call either
* by owner or with lock held -- it is OK for base, but not
* top, to move while resizings are in progress.
*/
final ForkJoinTask<?>[] growArray() {
ForkJoinTask<?>[] oldA = array;
int oldSize = oldA != null ? oldA.length : 0;
int size = oldSize > 0 ? oldSize << 1 : INITIAL_QUEUE_CAPACITY;
if (size < INITIAL_QUEUE_CAPACITY || size > MAXIMUM_QUEUE_CAPACITY)
throw new RejectedExecutionException("Queue capacity exceeded");
int oldMask, t, b;
ForkJoinTask<?>[] a = array = new ForkJoinTask<?>[size];
if (oldA != null && (oldMask = oldSize - 1) > 0 &&
(t = top) - (b = base) > 0) {
int mask = size - 1;
do { // emulate poll from old array, push to new array
int index = b & oldMask;
ForkJoinTask<?> x = (ForkJoinTask<?>)
QA.getAcquire(oldA, index);
if (x != null &&
QA.compareAndSet(oldA, index, x, null))
a[b & mask] = x;
} while (++b != t);
VarHandle.releaseFence();
}
return a;
}
/**
* Takes next task, if one exists, in LIFO order. Call only
* by owner in unshared queues.
*/
final ForkJoinTask<?> pop() {
int b = base, s = top, al, i; ForkJoinTask<?>[] a;
if ((a = array) != null && b != s && (al = a.length) > 0) {
int index = (al - 1) & --s;
ForkJoinTask<?> t = (ForkJoinTask<?>)
QA.get(a, index);
if (t != null &&
QA.compareAndSet(a, index, t, null)) {
top = s;
VarHandle.releaseFence();
return t;
}
}
return null;
}
/**
* Pops and executes up to limit consecutive tasks or until empty.
*
* @param limit max runs, or zero for no limit
*/
final void localPopAndExec(int limit) {
for (;;) {
int b = base, s = top, al; ForkJoinTask<?>[] a;
if ((a = array) != null && b != s && (al = a.length) > 0) {
int index = (al - 1) & --s;
ForkJoinTask<?> t = (ForkJoinTask<?>)
QA.getAndSet(a, index, null);
if (t != null) {
top = s;
VarHandle.releaseFence();
t.doExec();
if (limit != 0 && --limit == 0)
break;
}
else
break;
}
else
break;
}
}
/**
* Tries to expand buffer and add item, returning true on
* success. Currently fails only if out of memory.
*/
final boolean growAndOffer(T item, Object[] a, int t) {
int cap = 0, newCap = 0;
Object[] newArray = null;
if (a != null && (cap = a.length) > 0 && (newCap = cap << 1) > 0) {
try {
newArray = new Object[newCap];
} catch (OutOfMemoryError ex) {
}
}
if (newArray == null)
return false;
else { // take and move items
int newMask = newCap - 1;
newArray[t-- & newMask] = item;
for (int mask = cap - 1, k = mask; k >= 0; --k) {
Object x = QA.getAndSet(a, t & mask, null);
if (x == null)
break; // already consumed
else
newArray[t-- & newMask] = x;
}
array = newArray;
VarHandle.releaseFence(); // release array and slots
return true;
}
}
/**
* Doubles the capacity of array. Call either by owner or with
* lock held -- it is OK for base, but not top, to move while
* resizings are in progress.
*/
final void growArray(boolean locked) {
ForkJoinTask<?>[] newA = null;
try {
ForkJoinTask<?>[] oldA; int oldSize, newSize;
if ((oldA = array) != null && (oldSize = oldA.length) > 0 &&
(newSize = oldSize << 1) <= MAXIMUM_QUEUE_CAPACITY &&
newSize > 0) {
try {
newA = new ForkJoinTask<?>[newSize];
} catch (OutOfMemoryError ex) {
}
if (newA != null) { // poll from old array, push to new
int oldMask = oldSize - 1, newMask = newSize - 1;
for (int s = top - 1, k = oldMask; k >= 0; --k) {
ForkJoinTask<?> x = (ForkJoinTask<?>)
QA.getAndSet(oldA, s & oldMask, null);
if (x != null)
newA[s-- & newMask] = x;
else
break;
}
array = newA;
VarHandle.releaseFence();
}
}
} finally {
if (locked)
phase = 0;
}
if (newA == null)
throw new RejectedExecutionException("Queue capacity exceeded");
}
/**
* If present, removes task from queue and executes it.
*/
final void tryRemoveAndExec(ForkJoinTask<?> task) {
ForkJoinTask<?>[] a; int s, cap;
if ((a = array) != null && (cap = a.length) > 0 &&
(s = top) - base > 0) { // traverse from top
for (int m = cap - 1, ns = s - 1, i = ns; ; --i) {
int index = i & m;
ForkJoinTask<?> t = (ForkJoinTask<?>)QA.get(a, index);
if (t == null)
break;
else if (t == task) {
if (QA.compareAndSet(a, index, t, null)) {
top = ns; // safely shift down
for (int j = i; j != ns; ++j) {
ForkJoinTask<?> f;
int pindex = (j + 1) & m;
f = (ForkJoinTask<?>)QA.get(a, pindex);
QA.setVolatile(a, pindex, null);
int jindex = j & m;
QA.setRelease(a, jindex, f);
}
VarHandle.releaseFence();
t.doExec();
}
break;
}
}
}
}
/**
* Pops the given task only if it is at the current top.
*/
final boolean tryUnpush(ForkJoinTask<?> task) {
int b = base, s = top, al; ForkJoinTask<?>[] a;
if ((a = array) != null && b != s && (al = a.length) > 0) {
int index = (al - 1) & --s;
if (QA.compareAndSet(a, index, task, null)) {
top = s;
VarHandle.releaseFence();
return true;
}
}
return false;
}
/**
* If present, removes task from queue and executes it.
*/
final void tryRemoveAndExec(ForkJoinTask<?> task) {
ForkJoinTask<?>[] wa; int s, wal;
if (base - (s = top) < 0 && // traverse from top
(wa = array) != null && (wal = wa.length) > 0) {
for (int m = wal - 1, ns = s - 1, i = ns; ; --i) {
int index = i & m;
ForkJoinTask<?> t = (ForkJoinTask<?>)
QA.get(wa, index);
if (t == null)
break;
else if (t == task) {
if (QA.compareAndSet(wa, index, t, null)) {
top = ns; // safely shift down
for (int j = i; j != ns; ++j) {
ForkJoinTask<?> f;
int pindex = (j + 1) & m;
f = (ForkJoinTask<?>)QA.get(wa, pindex);
QA.setVolatile(wa, pindex, null);
int jindex = j & m;
QA.setRelease(wa, jindex, f);
}
VarHandle.releaseFence();
t.doExec();
}
break;
}
}
}
}
/**
* Tries to steal and run tasks within the target's
* computation until done, not found, or limit exceeded.
*
* @param task root of CountedCompleter computation
* @param limit max runs, or zero for no limit
* @return task status on exit
*/
final int localHelpCC(CountedCompleter<?> task, int limit) {
int status = 0;
if (task != null && (status = task.status) >= 0) {
for (;;) {
boolean help = false;
int b = base, s = top, al; ForkJoinTask<?>[] a;
if ((a = array) != null && b != s && (al = a.length) > 0) {
int index = (al - 1) & (s - 1);
ForkJoinTask<?> o = (ForkJoinTask<?>)
QA.get(a, index);
if (o instanceof CountedCompleter) {
CountedCompleter<?> t = (CountedCompleter<?>)o;
for (CountedCompleter<?> f = t;;) {
if (f != task) {
if ((f = f.completer) == null) // try parent
break;
}
else {
if (QA.compareAndSet(a, index, t, null)) {
top = s - 1;
VarHandle.releaseFence();
t.doExec();
help = true;
}
break;
}
}
}
}
if ((status = task.status) < 0 || !help ||
(limit != 0 && --limit == 0))
break;
}
}
return status;
}
/**
* Streamlined bulk insertion to initialize from elements of
* given sorted map. Call only from constructor or clone
* method.
*/
private void buildFromSorted(SortedMap<K, ? extends V> map) {
if (map == null)
throw new NullPointerException();
Iterator<? extends Map.Entry<? extends K, ? extends V>> it =
map.entrySet().iterator();
/*
* Add equally spaced indices at log intervals, using the bits
* of count during insertion. The maximum possible resulting
* level is less than the number of bits in a long (64). The
* preds array tracks the current rightmost node at each
* level.
*/
@SuppressWarnings("unchecked")
Index<K,V>[] preds = (Index<K,V>[])new Index<?,?>[64];
Node<K,V> bp = new Node<K,V>(null, null, null);
Index<K,V> h = preds[0] = new Index<K,V>(bp, null, null);
long count = 0;
while (it.hasNext()) {
Map.Entry<? extends K, ? extends V> e = it.next();
K k = e.getKey();
V v = e.getValue();
if (k == null || v == null)
throw new NullPointerException();
Node<K,V> z = new Node<K,V>(k, v, null);
bp = bp.next = z;
if ((++count & 3L) == 0L) {
long m = count >>> 2;
int i = 0;
Index<K,V> idx = null, q;
do {
idx = new Index<K,V>(z, idx, null);
if ((q = preds[i]) == null)
preds[i] = h = new Index<K,V>(h.node, h, idx);
else
preds[i] = q.right = idx;
} while (++i < preds.length && ((m >>>= 1) & 1L) != 0L);
}
}
if (count != 0L) {
VarHandle.releaseFence(); // emulate volatile stores
addCount(count);
head = h;
VarHandle.fullFence();
}
}
/**
* Reconstitutes this map from a stream (that is, deserializes it).
* @param s the stream
* @throws ClassNotFoundException if the class of a serialized object
* could not be found
* @throws java.io.IOException if an I/O error occurs
*/
@SuppressWarnings("unchecked")
private void readObject(final java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in the Comparator and any hidden stuff
s.defaultReadObject();
// Same idea as buildFromSorted
@SuppressWarnings("unchecked")
Index<K,V>[] preds = (Index<K,V>[])new Index<?,?>[64];
Node<K,V> bp = new Node<K,V>(null, null, null);
Index<K,V> h = preds[0] = new Index<K,V>(bp, null, null);
Comparator<? super K> cmp = comparator;
K prevKey = null;
long count = 0;
for (;;) {
K k = (K)s.readObject();
if (k == null)
break;
V v = (V)s.readObject();
if (v == null)
throw new NullPointerException();
if (prevKey != null && cpr(cmp, prevKey, k) > 0)
throw new IllegalStateException("out of order");
prevKey = k;
Node<K,V> z = new Node<K,V>(k, v, null);
bp = bp.next = z;
if ((++count & 3L) == 0L) {
long m = count >>> 2;
int i = 0;
Index<K,V> idx = null, q;
do {
idx = new Index<K,V>(z, idx, null);
if ((q = preds[i]) == null)
preds[i] = h = new Index<K,V>(h.node, h, idx);
else
preds[i] = q.right = idx;
} while (++i < preds.length && ((m >>>= 1) & 1L) != 0L);
}
}
if (count != 0L) {
VarHandle.releaseFence();
addCount(count);
head = h;
VarHandle.fullFence();
}
}