a-foundation/src/main/java/com/ajjpj/afoundation/concurrent/AThreadPoolImpl.java
@Override public List<AFuture<Void>> shutdown (ShutdownMode shutdownMode) {
        if (! shutdown.compareAndSet (false, true)) {
            throw new IllegalStateException ("pool can be shut down only once");
        }

        if (shutdownMode == ShutdownMode.SkipUnstarted || shutdownMode == ShutdownMode.InterruptRunning) {
            for (ASharedQueue sharedQueue: sharedQueues) {
                sharedQueue.clear ();
            }

            for (LocalQueue queue: localQueues) {
                //noinspection StatementWithEmptyBody
                while (queue.popFifo () != null) {
                    // do nothing, just drain the queue
                }
            }

            if (shutdownMode == ShutdownMode.InterruptRunning) {
                for (LocalQueue queue: localQueues) {
                    queue.thread.interrupt ();
                }
            }
        }

        final List<AFuture<Void>> result = new ArrayList<> ();

        for (LocalQueue localQueue : localQueues) {
            final ASettableFuture<Void> f = ASettableFuture.create ();
            sharedQueues[0].push (() -> {
                workerThreadLifecycleCallback.onPreDie (localQueue.thread);
                throw new PoolShutdown (f);
            });
            UNSAFE.unpark (localQueue.thread);
            result.add (f);

            f.onComplete (AThreadPool.SYNC_THREADPOOL, x -> workerThreadLifecycleCallback.onPostDie (localQueue.thread));
        }

        return result;
    }
@Override public List<AFuture<Void>> shutdown (ShutdownMode shutdownMode) {
        if (! shutdown.compareAndSet (false, true)) {
            throw new IllegalStateException ("pool can be shut down only once");
        }

        if (shutdownMode == ShutdownMode.SkipUnstarted || shutdownMode == ShutdownMode.InterruptRunning) {
            for (ASharedQueue sharedQueue: sharedQueues) {
                sharedQueue.clear ();
            }

            for (LocalQueue queue: localQueues) {
                //noinspection StatementWithEmptyBody
                while (queue.popFifo () != null) {
                    // do nothing, just drain the queue
                }
            }

            if (shutdownMode == ShutdownMode.InterruptRunning) {
                for (LocalQueue queue: localQueues) {
                    queue.thread.interrupt ();
                }
            }
        }

        final List<AFuture<Void>> result = new ArrayList<> ();

        for (LocalQueue localQueue : localQueues) {
            final ASettableFuture<Void> f = ASettableFuture.create ();
            sharedQueues[0].push (() -> {
                workerThreadLifecycleCallback.onPreDie (localQueue.thread);
                throw new PoolShutdown (f);
            });
            UNSAFE.unpark (localQueue.thread);
            result.add (f);

            f.onComplete (AThreadPool.SYNC_THREADPOOL, x -> workerThreadLifecycleCallback.onPostDie (localQueue.thread));
        }

        return result;
    }
This method shuts down the thread pool. The method finishes immediately, returning a separate AFuture for every worker thread. In order to combine them into a single
AFuture for all worker threads, use {@code AFuture.lift()} on the result.