Search code examples
javaexecutors

How to access the underlying queue of a ThreadpoolExecutor in a thread safe way


The getQueue() method provides access to the underlying blocking queue in the ThreadPoolExecutor, but this does not seem to be safe.

A traversal over the queue returned by this function might miss updates made to the queue by the ThreadPoolExecutor.

"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."

What would you do if you wanted to traverse the workQueue used by the ThreadPoolExecutor? Or is there an alternate approach?

This is a continuation of.. Choosing a data structure for a variant of producer consumer problem

Now, I am trying the multiple producer multiple consumer, but I want to use some existing threadpool, since I don't want to manage the threadpool myself, and also I want a callback when ThreadPoolExecutor has finished executing some task alongwith the ability to examine in a thread safe way the "inprogress transactions" data structure.


Solution

  • You can override the beforeExecute and afterExecute methods to let you know that a task has started and finished. You can override execute() to know when a task is added.

    The problem you have is that the Queue is not designed to be queried and a task can be consumed before you see it. One way around this is to create you own implementation of a Queue (perhaps overriding/wrapping a ConcurrentLinkedQueue)

    BTW: The queue is thread-safe, however it is not guaranteed you will see every entry.

    A ConcurrentLinkedQueue.iterator() is documented as

    Returns an iterator over the elements in this queue in proper sequence. The returned iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.