У меня много операций для нескольких потоков.
Следует разрешить приостанавливать вычисления и увеличивать / уменьшать количество потоков, а затем приостанавливать вычисления.
В данный момент я могу просто увеличить количество потоков - задачи, уже созданные 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
}
}
Основываясь на моем примере, давайте представим ситуацию:
- call setNumberOfThreads (5)
- call start ()
- fut создаст большую очередь с задачами, ожидающими обработки, после случайного числа 10000
- call suspendCalculations ()
- call setNumberOfThreads (2)
- call continueCalculations ()
Таким образом, потоки не могут быть сокращены - у нас есть 10000 задач, которые нужно обработать в очереди, поэтому нам нужно ждать, когда очередь опустеет.
Я хочу дождаться 5 задач на 5потоки закончатся, и задачи из очереди (10000) не будут переданы потокам, пока я не вызову continueCalculations.Таким образом, я могу вызвать setCorePoolSize (2) перед continueCalculations, потому что потоки не будут обрабатывать задачи из-за suspendCalculations