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
?
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;
}
}
}