具有单线程的计划执行程序服务

Scheduled Executor Service with single thread

我有一个计划执行器服务的示例代码,取自 Oracle 的站点。它创建一个核心池大小为 o 1 的 ScheduledExecutorService。它执行 2 个作业:首先它启动一个以固定间隔执行的重复任务,然后在延迟后终止相同的任务和服务本身。

 ScheduledExecutorService scheduledService = Executors.newScheduledThreadPool(1);
         //This will keep executing the task at fixed interval
         ScheduledFuture<?> futureTask = scheduledService.scheduleAtFixedRate(new RepeatedTask(), initialDelay, interval, TimeUnit.SECONDS);
         //A future task is returned which can be used to cancel the execution after sometime
         //Here we will cancel our repeated task after 100 seconds
         scheduledService.schedule(new TaskStopper(futureTask, scheduledService), 100, TimeUnit.SECONDS);

重复任务代码:

public class RepeatedTask implements Runnable{
    int count = 0;
    @Override
    public void run() {
        count++;
        System.out.println(count + ". Beep");
    }

}

停止任务

@Override
    public void run() {
        mFutureTask.cancel(true);
        System.out.println("Task stopped");
        mExecutorService.shutdownNow();
        boolean shutDown = mExecutorService.isShutdown();
        if(shutDown) {
            System.out.println("Executor shutdown");
        }else {
            System.out.println("Executor not shutdown");
        }
    }

我想了解,它是如何与线程池中的单个线程一起工作的。 由于我们的执行器服务执行两个任务并且几乎同时启动它们, 我们不应该有 2 个线程,即核心池大小为 2 的 ScheduledExecutorService。

虽然它工作正常。我只是想了解为什么它在单线程下运行良好。

对于任何线程池(包括ScheduledThreadPool),线程数可以小于任务数。线程池内部有一个任务队列,如果没有线程可用于执行任务,任务将不得不等待。

在您的示例中,在 t=100 秒时,需要执行两个任务。由于只有一个线程可用,它执行第一个任务(而第二个线程在队列中等待)。第一个任务完成后,线程从队列中选择第二个任务并完成它。

您可以打印出两个任务中的线程 ID,并可以验证它们确实由同一个线程处理。

编辑: 所以基本上,以固定间隔安排的任务会以固定间隔执行多次。在这些间隔期间,我们在池中的单个线程处于空闲状态,并且能够选择其他任务来执行。这就是一个线程执行两个任务的方式。