0
    final void push(ForkJoinTask<?> task) {
        ForkJoinTask<?>[] a; ForkJoinPool p;
        int b = base, s = top, n;
        if ((a = array) != null) {    // ignore if queue removed
            int m = a.length - 1;     // fenced write for task visibility
            U.putOrderedObject(a, ((m & s) << ASHIFT) + ABASE, task);
            U.putOrderedInt(this, QTOP, s + 1);
            if ((n = s - b) <= 1) {
                if ((p = pool) != null)
                    p.signalWork(p.workQueues, this);
            }
            else if (n >= m)
                growArray();
        }
    }

U.putOrderedObject and U.putOrderedInt set the array and top of WorkQueue. So why don't just use array[i]=task and top=s+1.I’m reading the source of ForkJoinPool and meet this problem.

the source from oracle jdk 1.8(1.8.0_131).

footmanff
  • 11
  • 3

1 Answers1

1

Unsafe handled the problem of fences before VarHandle. See Rob Austin's blog for some detail. The F/J author does every trick in the book to gain speed. The code prior to VarHandle is most difficult to understand, now a little less so.

Rather than using standard Java arrays (like ConcurrentLinkedQueue with it's additional overhead) he uses his own raw array.

edharned
  • 1,884
  • 1
  • 19
  • 20