Servizio esecutore pianificato con thread singolo
Ho un codice di esempio per Scheduled Executor Service, preso dal sito di Oracle. Crea uno ScheduledExecutorService con la dimensione del pool di base o 1. Esegue 2 lavori: prima avvia un'attività ripetuta eseguita a intervalli fissi e quindi termina la stessa attività e il servizio stesso dopo un ritardo.
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);
Il codice attività ripetuto:
public class RepeatedTask implements Runnable{
int count = 0;
@Override
public void run() {
count++;
System.out.println(count + ". Beep");
}
}
L'attività di arresto
@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");
}
}
Voglio capire, come funziona con un singolo thread nel pool di thread. Poiché il nostro servizio di esecutore esegue due attività e le avvia entrambe quasi contemporaneamente, non dovremmo avere 2 thread, ovvero uno ScheduledExecutorService con una dimensione del pool di base di 2.
Funziona bene però. Voglio solo capire perché funziona bene con un singolo thread.
Risposte
Per qualsiasi pool di thread (incluso ScheduledThreadPool), il numero di thread può essere inferiore al numero di attività. I pool di thread hanno internamente una coda di attività, in cui un'attività dovrà attendere se nessun thread è disponibile per eseguire l'attività.
Nel tuo esempio, at = 100 secondi, devono essere eseguite due attività. Poiché è disponibile un solo thread, esegue la prima attività (mentre la seconda attende in coda). Una volta completata la prima attività, il thread seleziona la seconda attività dalla coda e la completa.
È possibile stampare l'ID del thread in entrambe le attività e verificare che siano effettivamente elaborate dallo stesso thread.
Modifica: quindi, in pratica, l'attività pianificata a intervalli fissi viene eseguita più volte con intervalli fissi intermedi. Durante questi intervalli, il nostro singolo thread nel pool è inattivo ed è in grado di scegliere altre attività per l'esecuzione. È così che un singolo thread esegue entrambe le attività.