具有单线程的计划执行程序服务
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,并可以验证它们确实由同一个线程处理。
编辑:
所以基本上,以固定间隔安排的任务会以固定间隔执行多次。在这些间隔期间,我们在池中的单个线程处于空闲状态,并且能够选择其他任务来执行。这就是一个线程执行两个任务的方式。
我有一个计划执行器服务的示例代码,取自 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,并可以验证它们确实由同一个线程处理。
编辑: 所以基本上,以固定间隔安排的任务会以固定间隔执行多次。在这些间隔期间,我们在池中的单个线程处于空闲状态,并且能够选择其他任务来执行。这就是一个线程执行两个任务的方式。