a-foundation/src/main/java/com/ajjpj/afoundation/concurrent/LocalQueue.java
Runnable popFifo () {
        long _base, _top;

        while (true) {
            // reading 'base' with volatile semantics emits the necessary barriers to ensure visibility of 'top'
            _base = UNSAFE.getLongVolatile (this, OFFS_BASE);
            _top = top;

            if (_base == _top) {
                // Terminate the loop: the queue is empty.
                //TODO verify that Hotspot optimizes this kind of return-from-the-middle well
                return null;
            }

            // a regular read is OK here: 'push()' emits a store barrier after storing the task, 'popLifo()' modifies it with CAS, and 'popFifo()' does
            //  a volatile read of 'base' before reading the task
            final Runnable result = tasks[asArrayindex (_base)];

            // result == null means that another thread concurrently fetched the task from under our nose.
            // checking _base against a re-read 'base' with volatile semantics avoids wrap-around race - 'base' could have incremented by a multiple of the queue's size between
            //   our first reading it and fetching the task at that offset, which would cause the increment inside the following if block to significantly decrement it and
            //   wreak havoc.
            // CAS ensures that only one thread gets the task, and allows GC when processing is finished
            if (result != null && _base == UNSAFE.getLongVolatile(this, OFFS_BASE) && UNSAFE.compareAndSwapObject (tasks, taskOffset (_base), result, null)) {
                UNSAFE.putLongVolatile (this, OFFS_BASE, _base+1); //TODO is 'putOrdered' sufficient?
                return result;
            }
        }
    }
Runnable popFifo () {
        long _base, _top;

        while (true) {
            // reading 'base' with volatile semantics emits the necessary barriers to ensure visibility of 'top'
            _base = UNSAFE.getLongVolatile (this, OFFS_BASE);
            _top = top;

            if (_base == _top) {
                // Terminate the loop: the queue is empty.
                //TODO verify that Hotspot optimizes this kind of return-from-the-middle well
                return null;
            }

            // a regular read is OK here: 'push()' emits a store barrier after storing the task, 'popLifo()' modifies it with CAS, and 'popFifo()' does
            //  a volatile read of 'base' before reading the task
            final Runnable result = tasks[asArrayindex (_base)];

            // result == null means that another thread concurrently fetched the task from under our nose.
            // checking _base against a re-read 'base' with volatile semantics avoids wrap-around race - 'base' could have incremented by a multiple of the queue's size between
            //   our first reading it and fetching the task at that offset, which would cause the increment inside the following if block to significantly decrement it and
            //   wreak havoc.
            // CAS ensures that only one thread gets the task, and allows GC when processing is finished
            if (result != null && _base == UNSAFE.getLongVolatile(this, OFFS_BASE) && UNSAFE.compareAndSwapObject (tasks, taskOffset (_base), result, null)) {
                UNSAFE.putLongVolatile (this, OFFS_BASE, _base+1); //TODO is 'putOrdered' sufficient?
                return result;
            }
        }
    }
Runnable popFifo ( ) { long _base , _top ; while ( true ) { // reading 'base' with volatile semantics emits the necessary barriers to ensure visibility of 'top' _base = UNSAFE . getLongVolatile ( this , OFFS_BASE ) ; _top = top ; if ( _base == _top ) { // Terminate the loop: the queue is empty. //TODO verify that Hotspot optimizes this kind of return-from-the-middle well return null ; } // a regular read is OK here: 'push()' emits a store barrier after storing the task, 'popLifo()' modifies it with CAS, and 'popFifo()' does //  a volatile read of 'base' before reading the task final Runnable result = tasks [ asArrayindex ( _base ) ] ; // result == null means that another thread concurrently fetched the task from under our nose. // checking _base against a re-read 'base' with volatile semantics avoids wrap-around race - 'base' could have incremented by a multiple of the queue's size between //   our first reading it and fetching the task at that offset, which would cause the increment inside the following if block to significantly decrement it and //   wreak havoc. // CAS ensures that only one thread gets the task, and allows GC when processing is finished if ( result != null && _base == UNSAFE . getLongVolatile ( this , OFFS_BASE ) && UNSAFE . compareAndSwapObject ( tasks , taskOffset ( _base ) , result , null ) ) { UNSAFE . putLongVolatile ( this , OFFS_BASE , _base + 1 ) ; //TODO is 'putOrdered' sufficient? return result ; } } }
Fetch (and remove) a task from the bottom of the queue, i.e. FIFO semantics. This method can be called by any thread.
Fetch ( and remove ) a task from the bottom of the queue i . e . FIFO semantics . This method can be called by any thread .