Executors.newScheduledThreadPool în Java

Creează un executor care rulează sarcini după o întârziere sau periodic (la fiecare N secunde).

Sintaxă
static ScheduledExecutorService newScheduledThreadPool(int nFire)

ScheduledFuture<?> schedule(Runnable sarcina, long intarziere, TimeUnit unitate)
ScheduledFuture<?> scheduleAtFixedRate(Runnable sarcina, long intarziereInitiala, long perioada, TimeUnit unitate)
ScheduledFuture<?> scheduleWithFixedDelay(Runnable sarcina, long intarziereInitiala, long pauza, TimeUnit unitate)

Ce face Executors.newScheduledThreadPool

newScheduledThreadPool(n) returnează un ScheduledExecutorService: un executor care poate programa sarcini în timp. Este înlocuitorul modern al clasei vechi Timer.

schedule(sarcina, 2, TimeUnit.SECONDS) rulează sarcina o dată, după 2 secunde. scheduleAtFixedRate o rulează periodic, la intervale fixe măsurate de la începutul fiecărei rulări. scheduleWithFixedDelay lasă o pauză fixă între sfârșitul unei rulări și începutul următoarei.

Sarcinile periodice nu se opresc singure: le oprești cu cancel pe ScheduledFuture primit sau cu shutdown() pe executor. Dacă o rulare aruncă o excepție, următoarele rulări nu mai au loc.

Parametri

Parametru Descriere
nFire Câte fire păstrează executorul pentru sarcinile programate.
intarziere După cât timp rulează sarcina.
perioada / pauza Intervalul dintre rulări, pentru sarcinile periodice.
unitate Unitatea de timp (TimeUnit.MILLISECONDS, SECONDS…).

Ce returnează

Un ScheduledExecutorService. Metodele schedule… returnează un ScheduledFuture.

Exemple

Exemplul 1: Mementouri cu întârzieri diferite

Sarcinile sunt trimise în altă ordine, dar rulează în ordinea întârzierilor.

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        ScheduledExecutorService ceas = Executors.newScheduledThreadPool(1);
        ceas.schedule(() -> System.out.println("300 ms: Pleacă trenul spre Brașov"), 300, TimeUnit.MILLISECONDS);
        ceas.schedule(() -> System.out.println("100 ms: Ia biletul"), 100, TimeUnit.MILLISECONDS);
        ceas.schedule(() -> System.out.println("200 ms: Mergi la peronul 3"), 200, TimeUnit.MILLISECONDS);
        ceas.shutdown();
        ceas.awaitTermination(2, TimeUnit.SECONDS);
        System.out.println("Toate mementourile au rulat");
    }
}

Rezultat

100 ms: Ia biletul
200 ms: Mergi la peronul 3
300 ms: Pleacă trenul spre Brașov
Toate mementourile au rulat

Exemplul 2: O verificare periodică, oprită după 3 rulări

Sarcina rulează la fiecare 100 ms. Un CountDownLatch așteaptă trei rulări, apoi sarcina este anulată.

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        ScheduledExecutorService ceas = Executors.newScheduledThreadPool(1);
        AtomicInteger nr = new AtomicInteger();
        CountDownLatch treiRulari = new CountDownLatch(3);
        ScheduledFuture<?> verificare = ceas.scheduleAtFixedRate(() -> {
            if (nr.get() < 3) {
                System.out.println("Verific stocul, rularea " + nr.incrementAndGet());
                treiRulari.countDown();
            }
        }, 0, 100, TimeUnit.MILLISECONDS);
        treiRulari.await();
        verificare.cancel(false);
        ceas.shutdown();
        System.out.println("Anulată: " + verificare.isCancelled());
    }
}

Rezultat

Verific stocul, rularea 1
Verific stocul, rularea 2
Verific stocul, rularea 3
Anulată: true

Greșeli frecvente

  • Lași o excepție să iasă din sarcina periodică. Executorul oprește în liniște toate rulările următoare. Prinde excepțiile în interiorul sarcinii.
  • Uiți shutdown(). Firul executorului ține programul pornit la nesfârșit.
  • Folosești scheduleAtFixedRate pentru o sarcină care durează mai mult decât perioada. Rulările nu se suprapun, ci se adună întârziere după întârziere; folosește scheduleWithFixedDelay.

Comenzi înrudite

  • Executors: Clasa cu metode statice care creează executori: cu număr fix de fire, cu un singur fir, cu fire virtuale sau programate.
  • ExecutorService: Un grup de fire de execuție care primește sarcini și le rulează; se oprește cu shutdown() și se așteaptă cu awaitTermination().
  • TimeUnit: Enumerarea unităților de timp (SECONDS, MINUTES…) folosită la așteptări; face conversii și pauze ușor de citit.
  • CountDownLatch: Un numărător pentru așteptare: await() blochează până când alte fire apelează countDown() de N ori.
  • Future.cancel: Anulează o sarcină: dacă nu a pornit, nu mai rulează; dacă rulează, o poate întrerupe.