I'm reading the source code of CountedCompleter in JDK9, here is the code related to my question:
public abstract class CountedCompleter<T> extends ForkJoinTask<T> {
/** The number of pending tasks until completion */
volatile int pending;
// VarHandle mechanics
private static final VarHandle PENDING;
static {
try {
MethodHandles.Lookup l = MethodHandles.lookup();
PENDING = l.findVarHandle(CountedCompleter.class, "pending", int.class);
} catch (ReflectiveOperationException e) {
throw new ExceptionInInitializerError(e);
}
}
/**
* Sets the pending count to the given value.
*
* @param count the count
*/
public final void setPendingCount(int count) {
pending = count;
}
/**
* Adds (atomically) the given value to the pending count.
*
* @param delta the value to add
*/
public final void addToPendingCount(int delta) {
PENDING.getAndAdd(this, delta);
}
/**
* If the pending count is nonzero, (atomically) decrements it.
*
* @return the initial (undecremented) pending count holding on entry
* to this method
*/
public final int decrementPendingCountUnlessZero() {
int c;
do {} while ((c = pending) != 0 &&
!PENDING.weakCompareAndSet(this, c, c - 1));
return c;
}
}
Here are my questions:
- Why it uses pending and
PENDING? why not just use something likeAtomicInteger? - Why sometimes it uses pending, for example in
setPendingCount(), but sometimes it usesPENDING, for example inaddToPendingCount(). And it even uses both, for example indecrementPendingCountUnlessZero()