9

我正在使用 aScheduledExecutorService执行以固定速率调用服务的任务。服务可能会向任务返回一些数据。该任务将数据存储在队列中。其他一些线程慢慢地从队列中挑选项目

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 直到任务填充的队列被清除。

4

2 回答 2

4

你可以做

if(!queue.isEmpty()) return; 

在开始时。

如果您使用的是具有队列的 ScheduledExecutorService,为什么要使用它来添加到另一个队列。不能只在服务中使用队列吗?

于 2011-07-01T08:13:33.350 回答
3

当执行器关闭时,它不再接受新任务并等待当前任务终止。但是你不想终止你的执行者,只是暂停它。

所以你可以做的是,在你的任务中你只处理一个空队列。因为你的任务只是不时执行,所以当没有处理要做的时候,它的 CPU 消耗将接近 0。这是“if(!queue.isEmpty()) 返回;” 来自彼得劳里的回应。

其次,您使用阻塞队列。这意味着如果您在队列为空时调用方法 take() 来获取队列中的元素,则执行线程将等待直到某个元素自动添加到队列中。

所以:

  • 您不能暂停执行程序,即使它会使您的代码复杂化。
  • 阻塞队列的设计正是您需要的:如果队列为空,则阻塞任务。
  • 如果您愿意,您可以让周期性任务运行并检查队列是否为空。
  • 无论如何,您应该已经在您的任务中使用了一种或另一种方式,否则当队列为空时您将有 NullPointerException。
于 2011-07-01T08:36:57.580 回答