Приостановить ScheduledExecutorService


Я использую ScheduledExecutorService для выполнения задачи, которая вызывает службу с фиксированной скоростью. Служба может возвращать некоторые данные в задачу. Задача хранит данные в очереди. Некоторые другие потоки медленно выбирают элементы из очереди

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class EverlastingThread implements Runnable {

    private ScheduledExecutorService executorService;
    private int time;
    private TimeUnit timeUnit;
    private BlockingQueue<String> queue = new LinkedBlockingQueue<String>(500);

    public EverlastingThread(ScheduledExecutorService executorService, int time, TimeUnit timeUnit) {
        this.executorService = executorService;
        this.time = time;
        this.timeUnit = timeUnit;
    }

    public void run() {

        // call the service. if Service returns any data put it an the queue
        queue.add("task");
    }

    public void callService() throws Exception {
        // while queue has stuff dont exucute???????????

        executorService.scheduleAtFixedRate(this, 0, time, timeUnit);
    }
}

Как приостановить службу executorService до тех пор, пока не будет очищена очередь, заполненная задачей.

2 9

2 ответа:

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

Итак, что вы можете сделать, так это то, что в своей задаче вы просто имеете дело с пустой очередью. Поскольку ваша задача должна выполняться только время от времени, потребление процессора будет близко к 0 для нее, когда нет обработки, чтобы сделать. это и есть "если(!очередь.isEmpty ()) return; " от ответа Питера Лоури.

Во-вторых, вы используете блокирующая очередь. Это означает, что если вы вызовете метод take() для получения элемента в очереди, пока очередь пуста, поток исполнителя будет ждать, пока какой-то элемент не будет добавлен в очередь автоматически.

Итак:

  • вы не можете поставить исполнителя на паузу даже это усложнило бы ваш код.
  • блокирующую очередь делают по замыслу точно что вам нужно: блокировка задачи, если очередь пуста.
  • Если вы предпочитаете, вы можете просто позволить периодический запуск задачи и проверка наличия очередь пусто.
  • вы уже должны использовать один или другой путь в вашей задаче в любом случае в противном случае вы бы так и сделали NullPointerException, когда очередь быть пустой.

Вы можете сделать

if(!queue.isEmpty()) return; 

В самом начале.

Если вы используете ScheduledExecutorService, который имеет очередь, почему вы используете его для добавления в другую очередь. Нельзя ли просто воспользоваться очередью в сервисе?