繁体   English   中英

执行器服务和scheduleWithFixedDelay()

[英]Executor Service and scheduleWithFixedDelay()

这是我的任务。 我在一个类中有一个静态的作业队列,还有一个将作业添加到队列的静态方法。 有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个。 我究竟做错了什么? 谢谢!

从文档中:

如果此任务的任何执行花费的时间超过其周期,则后续执行可能会开始得较晚,但不会同时执行。

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

您正在以固定的延迟运行ScheduledExecutorService ,这意味着您的作业将一个接一个地运行。 使用固定线程池,并一次提交3个线程。 这是带有示例的说明

如果声明Job extends Runnable那么您的代码将大大简化:

首先,在全球可访问的地方声明执行器:

public static final ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS);

然后添加如下工作:

executor.submit(new Job());

大功告成

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM