如何在Java中跟踪线程池中的Runnables?

时间:2013-06-06 13:06:24

标签: java multithreading concurrency threadpool

我正在使用Map of Threads和相关的runnable对象来跟踪runnables。当抛出interruptedException时,我想要访问当前线程及其可运行对象。

Map<Thread, Runnable> myMap = new Map<Thread, Runnable>();
ExecutorService pool = Executors.newFixedThreadPool(5);
pool.execute(new myRunnable());

但是当我将runnable添加到线程池时,我想不出一种填充Map的方法。

如何在包含Thread及其runnable对象的地图中添加一个条目?

4 个答案:

答案 0 :(得分:3)

您可以使用ThreadPoolExecutor的钩子方法:

    final Map<Runnable, Thread> map = new ConcurrentHashMap<Runable, Thread>();
    ExecutorService pool = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()) {
        @Override
        protected void beforeExecute(Thread t, Runnable r) {
            map.put(r, t);
        }

        @Override
        protected void afterExecute(Runnable r, Throwable t) {
            map.remove(r);
        }
    };

答案 1 :(得分:3)

你从错误的角度接近它。提交到主题后,您应该认为您的工作已经完成。发生的任何中断都应由执行线程处理。

例如

public void run(){
    try{
      //do some work that responds to interruption
    }catch(InterruptedException ex){
       //clean up
    }
}

或者

public void run(){
    if(Thread.currentThread().isInterrtuped()){
        //clean up
        return;
    }
]

答案 2 :(得分:1)

ExecutorService背后的想法是从正在使用的线程中抽象出来。您可以覆盖myRunnable以泄漏信息。

所以你打电话给

pool.execute(new myRunnable(myMap));

然后在myRunnable中让构造函数保存对myMap的引用并添加

myMap.put(this,originalRunnableObject)

到run方法 - 其中originalRunnableObject是对此的保存引用。当然你需要你的地图是一个并发的地图(你不能像你想要的那样实例化地图界面)。

然而,我必须首先问你为什么要这样做,因为我说Executor应该提供一个你似乎想要颠覆的抽象层。

答案 3 :(得分:0)

    // Map might cause concurrent modifications, Queue may be a better choice.
    final BlockingQueue<Pair<Thread, Runnable>> interruptedRunnable = new LinkedBlockingDeque<>(0);
    threadPool.execute(new Runnable() {
        @Override
        public void run() {
            try {
                // TODO do something here?

                if (Thread.interrupted()) {
                    interruptedRunnable.add(Pair.of(Thread.currentThread(), this));
                    return;
                }
            } catch (InterruptedException _) {
                interruptedRunnable.add(Pair.of(Thread.currentThread(), this));
            }
        }
    });

    // TODO polling ...
    while (true) {
        try {

            // TODO adjust timeout
            Pair<Thread, Runnable> x = interruptedRunnable.poll(1, TimeUnit.MINUTES);

            if (null != x) {
                // check x.
            }
            // TODO
        } catch (InterruptedException _) {
         break;   
        }
    }