Пауза ScheduledExecutorService - PullRequest
9 голосов
/ 01 июля 2011

Я использую 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 ]

4 голосов
/ 01 июля 2011

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

if(!queue.isEmpty()) return; 

в начале.

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

3 голосов
/ 01 июля 2011

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

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

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

Итак:

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