2

我正在使用线程映射和关联的可运行对象来跟踪可运行对象。抛出这个背后的目的interruptedException是,我想访问当前线程及其可运行对象。

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

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

如何将条目添加到包含 Thread 及其可运行对象的映射中?

4

4 回答 4

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;
    }
]
于 2013-06-06T13:16:10.530 回答
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);
        }
    };
于 2013-06-06T13:14:02.460 回答
1

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

所以你会打电话

pool.execute(new myRunnable(myMap));

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

myMap.put(this,originalRunnableObject)

到 run 方法 - originalRunnableObject 是对此的保存引用。当然你需要你的地图是一个并发地图(你不能像你试图做的那样实例化 Map 接口)。

但是,首先必须要问为什么要这样做,正如我所说的那样,Executor 应该提供一个您似乎想要颠覆的抽象层。

于 2013-06-06T13:13:13.827 回答
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;   
        }
    }
于 2018-08-24T03:15:21.700 回答