Как вернуть задачи обратно в BlockingQueue ThreadPoolExecutor? - PullRequest
1 голос
/ 26 июня 2019

Я разрабатываю сервис, который будет обрабатывать большие файлы одновременно.Я хочу использовать ThreadPoolExecutor для своих целей, но проблема в том, что по умолчанию ThreadPoolExecutor сохраняет входящие задачи в BlockingQueue, если все потоки заняты.

Представьте себе ситуацию, когда у нас есть 10 файлов по 10 ГБ каждый и 5 потоков для выполнения 10 задач анализа файлов, я хочу каждый поток:

  1. Взять задачу из очереди.
  2. Выполните некоторое количество работы (обработайте 1 ГБ файла отверстия).
  3. Приостановите задачу и верните ее в очередь.
  4. Возьмите другую задачу и повторяйте, пока все файлы не будут обработаны.

1 Ответ

2 голосов
/ 26 июня 2019

Это может быть возможно с использованием простой Java, но это зависит от того, может ли задача сама проверить контрольную точку.Вот эскиз:

Executor ex = ...

public class MyTask implements Runnable {
    private int next;  // The state of the computation 
    private int end;  //

    public MyTask(int start, int end) {
        this.next = start;
        this.end = end;

    public void run() {
        for (int i = next; i < end; i++) {
            // do stuff
            if (/* suspend task *) {
                this.next = i + 1;  // checkpoint task state
                executor.execute(this); // requeue this task
                return;  // release worker thread
            }
        }
        System.out.println("Finished task");
    }
}

for (...) {
    executor.execute(new MyTask(...));
}

Обратите внимание, что приостановка задачи состоит из записи текущего состояния вычисления в полях this, добавления this в очередь, а затем возврата для освобождения работника.нить.Когда приостановленная задача снова достигает заголовка очереди, исполнитель назначит ее рабочему потоку, и поток вызовет run(), который (должен) возобновит вычисления с контрольной точки.

...