Search code examples
javathreadpoolexecutordeque

How can I make a ThreadPoolExecutor use a deque?


I need a thread pool that may receive tasks to be inserted either into the back of the queue (as usual), or into the front of the queue (for priority tasks). Tasks should then be executed normally, polled from the head of the queue.

I realize this means creating my own ThreadPoolExecutor using a BlockingDeque, but that's not enough... How do I actually tell the thread pool to call the queue's offerFirst method instead of offer?


Solution

  • You need to pass the PriorityBlockingQueue to the ThreadPoolExecutor, probably using this constructor. Added example below of how to initialise the PriorityBlockingQueue with a comparator

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }
    

    Edit - Example to add a comparator to your priority queue

    import java.util.Comparator;
    import java.util.concurrent.PriorityBlockingQueue;
    import java.util.concurrent.BlockingQueue;
    
    public class PriorityBlockQueueTest {
    
        private static BlockingQueue<PriorityTask> taskQueue = new PriorityBlockingQueue<>(10,
                new Comparator<PriorityTask>() {
            @Override
            public int compare(PriorityTask o1, PriorityTask o2) {
                return o2.getData() - o1.getData();
            }
        });
    
        public static void main(String arg[]) {
            taskQueue.add(new PriorityTask(2, 10));
            taskQueue.add(new PriorityTask(1, 11));
    
            System.out.println(taskQueue);
        }
    
        private static class PriorityTask implements  Runnable {
            private int priority;
            private int data;
            public PriorityTask(int priority, int data) {
                this.priority = priority;
                this.data = data;
            }
    
            public int getData() {
                return data;
            }
    
            public void run() {
                System.out.println("Running something");
            }
    
            public String toString() {
                return "priority: " + priority + " data: " + data;
            }
        }
    }