Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reorder queue in Java's ThreadPoolExecutor [duplicate]

Possible Duplicate:
Java Executors: how can I set task priority?

I have a ThreadPoolExecutor built using a LinkedBlockingDequeue and I want to manipulate the underlying queue, however reading this in the documentation makes me very nervous.

Queue maintenance

Method getQueue() allows access to the work queue for purposes of monitoring and debugging. Use of this method for any other purpose is strongly discouraged. Two supplied methods, remove(java.lang.Runnable) and purge() are available to assist in storage reclamation when large numbers of queued tasks become cancelled.

Specifically I want to be able to

  1. Check the queue to see if an element already exists. I assume this is fine as no locking should be necessary to just view the elements in the queue.
  2. I want to reorder the queue based on some signal. This can obviously be troublesome. I was wondering if there is a preferred way to do this so that I won't mess up the queue for other uses.

Thanks

like image 345
Jon Avatar asked Sep 20 '12 17:09

Jon


1 Answers

getQueue() will always return the exact BlockingQueue<Runnable> that you pass into the ThreadPoolExecutor.

The worry with the documentation is that you could easily run into issues with double-running if you cannot guarantee the thread safety of the BlockingQueue. If you use a PriorityBlockingQueue, and only use remove and add (or, more directly, offer), then you will be safe, and you can even do it directly from the getQueue().

In other words, whenever your signal tells you that some Runnable's priority has changed, then you should remove it and check the result of the remove (true if removed), and only if it was actually removed, then you should re-add it. You are not guaranteed that something won't be picked up inbetween those operations, but you are at least guaranteed that you will not double-run the Runnable, which could easily happen if done with contains -> remove -> add.

Either that, or you can write your own implementation of a BlockingQueue that uses a Comparator (like the PriorityBlockingQueue) that finds the highest priority whenever asked for new data. This sounds like a lot more work given the various interfaces involved.

like image 65
pickypg Avatar answered Nov 06 '22 16:11

pickypg