ThreadPoolExecutor:提取挂起的任务

huangapple 未分类评论52阅读模式
英文:

ThreadPoolExecutor : Pull out hanged tasks

问题

我已经实现了ThreadPoolExecutor来调用任务。
而且,由于核心/队列大小配置不正确,任务似乎在I/O操作上挂起了。
我希望可以将那个挂起的线程中止,
以便队列中的其他线程开始执行。

有没有办法列出ThreadPoolExecutor中的线程,并中止挂起的线程?

英文:

I have implemented ThreadPoolExecutor to invoke a task.
And It seems tasks got hanged on I/O because of the core/queue size misconfiguration.
I want to pull the hanging thread out
so that the other threads in my queue starts executing.

Is there any way to list the threads inside a threadpoolexecutor and pull out the hanging thread?

答案1

得分: 0

import java.util.Set;
import java.util.concurrent.*;

public class ActiveTasksThreadPool extends ThreadPoolExecutor {

private final ConcurrentHashMap<Runnable, Boolean> activeTasks = new ConcurrentHashMap<>();

public ActiveTasksThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
    super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}

@Override
protected void beforeExecute(Thread t, Runnable r) {
    activeTasks.put(r, Boolean.TRUE);
    super.beforeExecute(t, r);
}

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

public Set<Runnable> getActiveTasks() {
    // the returned set will not throw a ConcurrentModificationException.
    return activeTasks.keySet();
}
}

// In order to set a timeout on thread tasks with `Future`:

ActiveTasksThreadPool executor = new ActiveTasksThreadPool(maxTasks, maxTasks, 10, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
Executors.newFixedThreadPool(2);

List<Future<Integer>> resultList = new ArrayList<>();

Random random = new Random();

for (int i=0; i<4; i++)
{
    Integer number = random.nextInt(10);
    FactorialCalculator calculator  = new FactorialCalculator(number);
    Future<Integer> result = executor.submit(calculator);
    result.get(100, TimeUnit.MILLISECONDS); // here is a timeout of 100 milisecond
}
英文:

You have control over the used executor, you could use the ThreadPoolExecutor's beforeExecute and afterExecute methods to keep track of running tasks and use that to create a getActiveTasks method.

import java.util.Set;
import java.util.concurrent.*;


public class ActiveTasksThreadPool extends ThreadPoolExecutor {

private final ConcurrentHashMap&lt;Runnable, Boolean&gt; activeTasks = new ConcurrentHashMap&lt;&gt;();

public ActiveTasksThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue&lt;Runnable&gt; workQueue) {
    super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}

@Override
protected void beforeExecute(Thread t, Runnable r) {

    activeTasks.put(r, Boolean.TRUE);
    super.beforeExecute(t, r);
}

@Override
protected void afterExecute(Runnable r, Throwable t) {

    super.afterExecute(r, t);
    activeTasks.remove(r);
}

public Set&lt;Runnable&gt; getActiveTasks() {
    // the returned set will not throw a ConcurrentModificationException.
    return activeTasks.keySet();
}

In order to set a timeout on thread tasks with Future:

 ActiveTasksThreadPool executor = new ActiveTasksThreadPool(maxTasks, maxTasks, 10, TimeUnit.SECONDS, new SynchronousQueue&lt;Runnable&gt;());Executors.newFixedThreadPool(2);
       
      List&lt;Future&lt;Integer&gt;&gt; resultList = new ArrayList&lt;&gt;();
       
      Random random = new Random();
       
      for (int i=0; i&lt;4; i++)
      {
          Integer number = random.nextInt(10);
          FactorialCalculator calculator  = new FactorialCalculator(number);
          Future&lt;Integer&gt; result = executor.submit(calculator);
          result .get(100, TimeUnit.MILLISECONDS); // here is a timeout of 100 milisecond
      }

huangapple
  • 本文由 发表于 2020年4月10日 15:26:19
  • 转载请务必保留本文链接:https://java.coder-hub.com/61135735.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定