Serviço de Executor Programado com thread único

Sep 02 2020

Eu tenho um código de amostra para Scheduled Executor Service, retirado do site da Oracle. Ele cria um ScheduledExecutorService com tamanho de pool de núcleo igual a 1. Ele faz 2 tarefas: primeiro, inicia uma tarefa repetida executada em intervalos fixos e, em seguida, elimina a mesma tarefa e o próprio serviço após um atraso.

 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);

O código de tarefa repetido:

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

}

A tarefa de parar

@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");
        }
    }

Eu quero entender como isso funciona com um único thread no pool de threads. Como nosso serviço executor executa duas tarefas e as inicia quase ao mesmo tempo, não deveríamos ter 2 threads, ou seja, um ScheduledExecutorService com tamanho de pool de núcleo de 2.

Mas funciona bem. Só quero entender por que funciona bem com um único thread.

Respostas

2 RishabhSharma Sep 02 2020 at 08:44

Para qualquer pool de threads (incluindo ScheduledThreadPool), o número de threads pode ser menor que o número de tarefas. Os pools de threads internamente têm uma fila de tarefas, na qual uma tarefa terá que esperar se nenhum thread estiver disponível para executá-la.

Em seu exemplo, em t = 100 segundos, duas tarefas precisam ser executadas. Visto que apenas um thread está disponível, ele executa a primeira tarefa (enquanto a segunda espera na fila). Assim que a primeira tarefa for concluída, o encadeamento seleciona a segunda tarefa da fila e a conclui.

Você pode imprimir o id do thread em ambas as tarefas e pode verificar se eles estão realmente sendo processados ​​pelo mesmo thread.

Editar: Então, basicamente, a tarefa agendada em intervalo fixo é executada várias vezes com intervalos fixos entre eles. Durante esses intervalos, nosso único thread no pool fica ocioso e é capaz de escolher outras tarefas para execução. É assim que um único thread executa ambas as tarefas.