簡體   English   中英

如何在Java中跟蹤線程池中的Runnables?

[英]How to keep track of Runnables in Thread Pool in Java?

我正在使用Map of Threads和相關的runnable對象來跟蹤runnables。 當拋出interruptedException時,我想要訪問當前線程及其runnable對象。

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

但是當我將runnable添加到線程池時,我想不出填充Map的方法。

如何在包含Thread及其runnable對象的地圖中添加一個條目?

您可以使用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);
        }
    };

您正在從錯誤的角度接近它。 提交到線程后,您應該會感到工作已完成。 發生的任何中斷都應由執行線程處理。

例如

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;
    }
]

ExecutorService背后的想法是從正在使用的線程中抽象出來。 您可以覆蓋myRunnable以泄漏信息。

所以你會打電話

pool.execute(new myRunnable(myMap));

然后在myRunnable中有構造函數保存對myMap的引用並添加

myMap.put(this,originalRunnableObject)

到run方法 - 其中originalRunnableObject是對此的保存引用。 當然,你需要你的地圖是一個並發的地圖(你不能像你想要的那樣實例化地圖界面)。

但是,首先要問為什么要這樣做,因為我說執行器應該給您一個抽象層,您似乎想顛覆這個抽象層。

    // 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;   
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM