package fault.java.concurrent;

import java.util.Comparator;
import java.util.NavigableSet;
import java.util.TreeSet;
import java.util.concurrent.Executor;

/**
 * Created by timbrooks on 12/2/14.
 */
public class ActionThreadPool implements Executor {

    private final NavigableSet<ThreadManager> pool;

    public ActionThreadPool(int threadCount) {
        pool = new TreeSet<>(new Comparator<ThreadManager>() {
            @Override
            public int compare(ThreadManager o1, ThreadManager o2) {
                int scheduledCount1 = o1.getScheduledCount();
                int scheduledCount2 = o2.getScheduledCount();
                if (scheduledCount1 > scheduledCount2) {
                    return 1;
                } else if (scheduledCount2 > scheduledCount1) {
                    return -1;
                }
                return 0;
            }
        });

    }

    @Override
    public void execute(Runnable action) {
        ThreadManager nextThread = pool.pollFirst();
        nextThread.submit(action);
        pool.add(nextThread);
    }

    public void signalTaskComplete(ThreadManager threadManager) {
        threadManager.decrementScheduledCount();
        pool.remove(threadManager);
        pool.add(threadManager);
    }

    private class ThreadManager {
        private final ExchangingQueue<Runnable> queue = new ExchangingQueue<>(10);
        private int scheduledCount = 0;

        private boolean submit(Runnable task) {
            boolean offered = queue.offer(task);
            if (offered) {
                ++scheduledCount;
            }
            return offered;
        }

        private void decrementScheduledCount() {
            --scheduledCount;
        }

        private int getScheduledCount() {
            return scheduledCount;
        }
    }
}

@@ -878,16 +878,118 @@
    %7D);%0A%0A
+        for (int i = 0; i %3C threadCount; ++i) %7B%0A            pool.add(new ThreadManager());%0A        %7D%0A%0A
     %7D%0A%0A 
@@ -1497,31 +1497,658 @@
 ate 
-int scheduledCount = 0;
+final Thread thread;%0A        // Volatile? Or Interrupt?%0A        private int scheduledCount = 0;%0A%0A        public ThreadManager() %7B%0A            thread = new Thread(new Runnable() %7B%0A                @Override%0A                public void run() %7B%0A                    for (; ; ) %7B%0A                        Runnable runnable = queue.blockingPoll();%0A                        runnable.run();%0A                        // Need to explore this strategy more.%0A                        if (thread.isInterrupted()) %7B%0A                            return;%0A                        %7D%0A                    %7D%0A                %7D%0A            %7D);%0A            thread.run();%0A        %7D
 %0A%0A  
@@ -2528,21 +2528,98 @@
 t;%0A        %7D
+%0A%0A        private void shutdown() %7B%0A            thread.interrupt();%0A        %7D
 %0A    %7D%0A%7D%0A

Add thread interrupt for pool