java - 执行器服务和scheduleWithFixedDelay()

标签 java multithreading executorservice

这是我的任务。我在一个类中有一个静态作业队列,还有一个将作业添加到队列中的静态方法。有 n 个线程从队列中轮询并执行拉取的作业。我需要让 n 个线程以一定间隔同时轮询。也就是说,所有 3 个应该每 5 秒轮询一次并寻找工作。

我有这个:

public class Handler {

    private static final Queue<Job> queue = new LinkedList<>();

    public static void initialize(int maxThreads) { // maxThreads == 3

        ScheduledExecutorService executorService =
            Executors.newScheduledThreadPool(maxThreads);

        executorService.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                Job job = null;
                synchronized(queue) {
                    if(queue.size() > 0) {
                        job = queue.poll();
                    }
                }
                if(job != null) {
                    Log.log("start job");
                    doJob(job);
                    Log.log("end job");
                }
            }    
        }, 15, 5, TimeUnit.SECONDS);

    }

}

当我添加 4 个任务时,我得到这个输出:

startjob
endjob
startjob
endjob
startjob
endjob
startjob
endjob

很明显,这些线程串行执行这些作业,而我需要它们一次完成 3 个。我究竟做错了什么?谢谢!

最佳答案

来自文档:

If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.

因此,您必须安排三个独立的任务以使它们同时运行。另请注意,调度执行器服务是一个固定的线程池,对于许多用例来说不够灵活。一个好的习惯用法是使用计划服务将任务提交到常规执行程序服务,该服务可以配置为可调整大小的线程池。

关于java - 执行器服务和scheduleWithFixedDelay(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20227984/

相关文章:

Java boolean 表达式并发行为

java - 长时间运行的线程实现有问题

java - 在 ScheduledExecutorService 中运行的任务本身中停止周期性任务

java - 如何将属性类型更改为字符串(WEKA - CSV 到 ARFF)

java - Android:BasicClientCookie/CookieStore 在 cookie 值周围添加引号

javascript - setInterval 的这种行为是否意味着 Javascript 中的多线程行为?

c - OMP 线程数多于内核,性能仍相同

java - 寻找具有线程池和最小调度延迟的 ExecutorService

java - 创建一个使用速度的可重用解析方法

java - 请参阅 .properties 文件中的类路径