I have a single thread pool ExecutorService object. At some time in the future tasks are added to be done using the submit() method. My understanding is that submit will submit add the submitted Runnable to the end of the list of tasks to be done. However I have a situation where based on a boolean I may want to submit the runnable to the front of the tasks to be executed. I don't want this to affect the current task, just that the next task done will be the one I just gave it. An example method is reproduced below. How do I do this?
Thanks
private ExecutorService singleLoadPool = Executors.newSingleThreadExecutor();
public void submitTask(Runnable run, boolean doNow) {
if (doNow)
singleLoadPool.submitFront(run); // This is the method I'm looking for
else
singleLoadPool.submit(run);
}
My preference would be use a LinkedBlockingDeque
. It directly supports positional inserts/removes - putFirst(e)/takeFirst()
and putLast(e)/takeLast()
- which is your primary requirement- you dont have to implement a Comparator
for your elements. Also this is bounded - which means that it provides safety against OutOfMemoryError
.
edit In response to latest question :
First , have the ExecutorService like
ExecutorService executorService = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, workQueue);
Second , the important question is : what is the workQueue
?
The workQueue
is a thin wrapper over any BlockingQueue
implementation , which delegates all its methods to a LinkedBlockingDeque
instance that it contains, except for the offer()
method , which is called on it by the ThreadPoolExecutor
and which needs to be overriden, like this :
public boolean offer(E e) {
if(doNow)
return linkedBlockingDequeInstance.offerFirst(e);
else
return linkedBlockingDequeInstance.offerLast(e);
}
Ofcourse when you override any method - you need to careful to preserve thread safety and its general contract.Definitely this requires careful thought and rigorous testing.
I think your best approach for this would be to instantiate a ThreadPoolExecutor
with a PriorityBlockingQueue
. Specifically, use a PriorityBlockingQueue constructor that takes in a Comparator
. Your Comparator
will be what you use to implement your 'priority'.
PriorityBlockingQueue<Runnable> workQueue = new PriorityBlockingQueue<Runnable>(20, yourPriorityComparator);
ExecutorService executorService = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, workQueue);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With