Removing jobs from ThreadPoolExecutor

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Removing jobs from ThreadPoolExecutor

Norman Elton
I'm using a ThreadPoolExecutor to handle incoming jobs. Jobs are  
either "low priority" or "high priority". I have a separate thread  
that monitors the queue to ensure that it does not get out of control.

I'd like for the monitoring thread to remove all low priority jobs if  
the queue gets above a certain size. Currently, I plan to loop  
through the queue, retrieved from ThreadPoolExecutor.getQueue(), and  
call ThreadPoolExecutor.remove() on all low priority jobs.

Is this the best way to accomplish this? Will there be any  
concurrency issues here? It appears that if I remove a job that has  
already been executed, the method will simply return false.

Thanks for any ideas,

Norman
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Removing jobs from ThreadPoolExecutor

Brian Goetz
Let me see if I understand what you're doing:

- You have one executor
- It shares both high and low priority tasks
- You want to reap low-priority tasks if the queue hits some bound so
that you can make room for more high priority tasks

Are you using a PriorityBlockingQueue for the tasks?  Is it bounded?

You might be able to do this with a custom BlockingQueue that derives
most of its functionality from PriorityBlockingQueue, but whose offer()
method kicks out old elements when the queue seems "too full".  (To do
this, you'd have to iterate the queue; the PriorityBlockingDeque class
from JSR166x would make this easier, because you could just delete the
last element(s) to make some room.)  Then you wouldn't need a separate
thread, because you'd intercept the offer() and only shed tasks when a
new high priority task shows up and there are already too many tasks on
the queue.

Norman Elton wrote:

> I'm using a ThreadPoolExecutor to handle incoming jobs. Jobs are  either
> "low priority" or "high priority". I have a separate thread  that
> monitors the queue to ensure that it does not get out of control.
>
> I'd like for the monitoring thread to remove all low priority jobs if  
> the queue gets above a certain size. Currently, I plan to loop  through
> the queue, retrieved from ThreadPoolExecutor.getQueue(), and  call
> ThreadPoolExecutor.remove() on all low priority jobs.
>
> Is this the best way to accomplish this? Will there be any  concurrency
> issues here? It appears that if I remove a job that has  already been
> executed, the method will simply return false.
>
> Thanks for any ideas,
>
> Norman
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Removing jobs from ThreadPoolExecutor

Dawid Kurzyniec
In reply to this post by Norman Elton
Norman Elton wrote:

> I'm using a ThreadPoolExecutor to handle incoming jobs. Jobs are  
> either "low priority" or "high priority". I have a separate thread  
> that monitors the queue to ensure that it does not get out of control.
>
> I'd like for the monitoring thread to remove all low priority jobs if  
> the queue gets above a certain size. Currently, I plan to loop  
> through the queue, retrieved from ThreadPoolExecutor.getQueue(), and  
> call ThreadPoolExecutor.remove() on all low priority jobs.
>
> Is this the best way to accomplish this? Will there be any  
> concurrency issues here? It appears that if I remove a job that has  
> already been executed, the method will simply return false.
>
Agreeing with Brian that using custom queue implementation is probably
the best solution, I am thinking, if you only have two priorities, maybe
you can get away with implementation of your queue that internally holds
two queues for high and low priority tasks? You then need to implement
the await/signal logic; internal queues may in fact be non-blocking. The
advantage of this is that you can quickly remove items from low-priority
queue on put, without iterating.

I don't quite see the solution based on PriorityQueue without using
iterators: Assuming that high-priority tasks should be run before
low-priority tasks, they must go at the top of the heap, and stuff can
only be removed from priority queue in log time and in proper order from
the top of the heap, not from the bottom.

If you need more than two priority levels, yet another possibility is to
use sorted list for the queue implementation, which makes it possible to
remove stuff from the end. I guess the only way to implement sorted list
in Java is to use SortedMap, with keys being (priority, uniqueID) pairs,
sorted in that order. (By priority first, FIFO next).

Regards,
Dawid

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Removing jobs from ThreadPoolExecutor

Norman Elton
Thanks Brian & David for the responses...

 >> - You have one executor
 >> - It shares both high and low priority tasks
 >> - You want to reap low-priority tasks if the queue hits some  
bound so that you can make room for more high priority tasks

Correct.

I am using a regular BlockingQueue (the default with a  
ThreadPoolExecutor). Although tasks are of two priorities, high  
priority jobs are not executed before low priority jobs. The  
"priority" (and perhaps I could have chosen a better term) only takes  
affect when the queue becomes too long.

I'll work on some of your suggestions and see how things go. Thanks  
again,

Norman


On Sep 2, 2005, at 1:12 PM, Dawid Kurzyniec wrote:

> Norman Elton wrote:
>
>
>> I'm using a ThreadPoolExecutor to handle incoming jobs. Jobs are  
>> either "low priority" or "high priority". I have a separate  
>> thread  that monitors the queue to ensure that it does not get out  
>> of control.
>>
>> I'd like for the monitoring thread to remove all low priority jobs  
>> if  the queue gets above a certain size. Currently, I plan to  
>> loop  through the queue, retrieved from ThreadPoolExecutor.getQueue
>> (), and  call ThreadPoolExecutor.remove() on all low priority jobs.
>>
>> Is this the best way to accomplish this? Will there be any  
>> concurrency issues here? It appears that if I remove a job that  
>> has  already been executed, the method will simply return false.
>>
>>
> Agreeing with Brian that using custom queue implementation is  
> probably the best solution, I am thinking, if you only have two  
> priorities, maybe you can get away with implementation of your  
> queue that internally holds two queues for high and low priority  
> tasks? You then need to implement the await/signal logic; internal  
> queues may in fact be non-blocking. The advantage of this is that  
> you can quickly remove items from low-priority queue on put,  
> without iterating.
>
> I don't quite see the solution based on PriorityQueue without using  
> iterators: Assuming that high-priority tasks should be run before  
> low-priority tasks, they must go at the top of the heap, and stuff  
> can only be removed from priority queue in log time and in proper  
> order from the top of the heap, not from the bottom.
>
> If you need more than two priority levels, yet another possibility  
> is to use sorted list for the queue implementation, which makes it  
> possible to remove stuff from the end. I guess the only way to  
> implement sorted list in Java is to use SortedMap, with keys being  
> (priority, uniqueID) pairs, sorted in that order. (By priority  
> first, FIFO next).
>
> Regards,
> Dawid
>
>

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest