Как предотвратить выполнение задач, ожидающих в очереди исполнителя свободного потока - PullRequest
0 голосов
/ 29 декабря 2018

У меня много операций для нескольких потоков.

Следует разрешить приостанавливать вычисления и увеличивать / уменьшать количество потоков, а затем приостанавливать вычисления.

В данный момент я могу просто увеличить количество потоков - задачи, уже созданные Future и ожидающие в очереди, обрабатываются все время и согласно документам потоки не могут быть уменьшены:

public voidsetCorePoolSize (int corePoolSize)

Устанавливает число ядер потоков.Это переопределяет любое значение, установленное в конструкторе. Если новое значение меньше текущего значения, избыточные существующие потоки будут прерваны, когда они в следующий раз станут бездействующими .Если больше, новые потоки, при необходимости, будут запущены для выполнения любых поставленных в очередь задач.

Итак, моя главная проблема: Как приостановить выполнение, чтобы не выполнять задачи, ожидающие в очереди?

Определение примера класса:

import java.util.concurrent.*;

public class Calc {

    private int numberOfThreads;
    private ThradPoolExecutor pool;
    private Future fut;

    public void setNumberOfThreads(int threads) {
        this.numberOfThreads = threads + 1;
    }

    public void start() {
        if(es == null){
            pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(numberOfThreads);
        } else {
            pool.setCorePoolSize(numberOfThreads);
            pool.setMaximumPoolSize(numberOfThreads);
        }
        fut = pool.submit(() -> {
            while (true) {
                pool.execute(this::calculate);
            }
        });
    }

    public void suspendCalculations() {
        fut.cancel(true);
    }

    public void continueCalculations() {
        start();
    }

    private void calculate() {
        // calculation logic, not important
    }
}

Основываясь на моем примере, давайте представим ситуацию:

  1. call setNumberOfThreads (5)
  2. call start ()
  3. fut создаст большую очередь с задачами, ожидающими обработки, после случайного числа 10000
  4. call suspendCalculations ()
  5. call setNumberOfThreads (2)
  6. call continueCalculations ()

Таким образом, потоки не могут быть сокращены - у нас есть 10000 задач, которые нужно обработать в очереди, поэтому нам нужно ждать, когда очередь опустеет.

Я хочу дождаться 5 задач на 5потоки закончатся, и задачи из очереди (10000) не будут переданы потокам, пока я не вызову continueCalculations.Таким образом, я могу вызвать setCorePoolSize (2) перед continueCalculations, потому что потоки не будут обрабатывать задачи из-за suspendCalculations

...