ThreadPoolExecutor: вытащить зависшие задачи - PullRequest
2 голосов
/ 10 апреля 2020

Я реализовал ThreadPoolExecutor для вызова задачи. И кажется, что задачи зависли на вводе / выводе из-за неправильной конфигурации размера ядра / очереди. Я хочу вытащить висящий поток, чтобы другие потоки в моей очереди начали выполняться.

Есть ли способ вывести список потоков в threadpoolexecutor и вытащить висящий поток?

1 Ответ

0 голосов
/ 10 апреля 2020

У вас есть контроль над используемым исполнителем, вы можете использовать методы ThreadPoolExecutor beforeExecute и afterExecute для отслеживания запущенных задач и использовать его для создания метода getActiveTasks.

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();
}

Для установки времени ожидания в задачах потока с 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
      }
...