HOWTO · Java

Ottieni l'ID thread in Java

Questo articolo esamina i metodi per ottenere l'ID del thread in Java.

In questa pagina

In Java, chiama Thread.getId() su un oggetto Thread per leggere il suo identificatore. Quando un’attività è in esecuzione in un executor, Thread.currentThread().getId() identifica il thread worker che la sta eseguendo. Gli esempi seguenti mostrano entrambi i casi: nessuno dei due valori identifica un thread pool o il nome di un thread. Usa il primo approccio quando hai già un riferimento a un Thread; usa il secondo dal codice eseguito all’interno di un’attività quando vuoi identificare il worker che la sta eseguendo.

Ottenere l’ID di un thread in Java con Thread.getId()

Crea un oggetto Thread, quindi chiama il suo metodo getId() per recuperarne l’identificatore come valore long. Il primo esempio crea due oggetti thread e legge entrambi gli ID. Non avvia i thread: per leggere gli identificatori di questi oggetti non è necessario avviarli. I valori degli identificatori vengono assegnati dal runtime e possono variare tra esecuzioni o ambienti; usa quindi il valore restituito durante l’esecuzione, senza fare affidamento sui numeri dell’esempio. Questo approccio è utile quando il codice ha un riferimento a un determinato Thread e deve distinguerlo da un altro.

public class GetThreadID {
  public static void main(String[] args) {
    Thread thread1 = new Thread();
    Thread thread2 = new Thread();

    System.out.println("Thread 1 ID: " + thread1.getId());
    System.out.println("Thread 2 ID: " + thread2.getId());
  }
}

Output illustrativo di una singola esecuzione:

Thread 1 ID: 12
Thread 2 ID: 13

Gli ID numerici riportati sopra sono illustrativi e dipendono dal runtime. Poiché i thread non vengono avviati, il programma stampa gli ID dei due oggetti nell’ordine delle istruzioni di stampa; i numeri dell’esempio non sono garantiti in un’altra esecuzione o ambiente.

Ottenere l’ID del thread worker corrente in un thread pool con Thread.currentThread().getId()

Un’attività inviata a un executor viene eseguita da uno dei suoi thread worker. Chiama Thread.currentThread().getId() dall’interno dell’attività per ottenere l’ID del worker che la sta eseguendo. Si tratta dell’ID di un worker, non dell’identificatore dell’executor o del pool. Un pool fisso riutilizza i propri worker, quindi attività diverse possono riportare lo stesso ID. È la pianificazione a determinare quale worker gestisce ciascuna attività; sia l’ordine delle attività sia gli ID numerici possono variare. Questa distinzione è utile per diagnosticare quale thread ha svolto una determinata unità di lavoro: il numero restituito descrive il worker in esecuzione in quel momento, non l’executor che ha pianificato l’attività.

L’esempio invia cinque attività, stampa il numero di ciascuna e l’ID del relativo worker, quindi arresta l’executor. shutdown() impedisce l’accettazione di nuove attività e consente a quelle già inviate di completarsi. awaitTermination attende il completamento per un massimo di un minuto senza ricorrere all’attesa attiva. Se il lavoro richiede più tempo, il programma segnala che l’attesa è scaduta; la richiesta di arresto è già stata inviata, quindi le attività in coda possono continuare. Nel codice di produzione, scegli un timeout adatto al lavoro dell’applicazione e stabilisci come gestire le attività che non terminano in tempo. Se devi scegliere i dettagli dell’API per una specifica versione di Java, consulta la documentazione relativa a quella versione: qui non è indicata una versione di destinazione.

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

public class GetThreadID {
  public static void main(String[] args) throws InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(2);

    for (int i = 1; i <= 5; i++) {
      final int taskNumber = i;
      executor.execute(() -> {
        long workerId = Thread.currentThread().getId();
        System.out.println("Task " + taskNumber + " ran on worker ID " + workerId);
      });
    }

    executor.shutdown();
    boolean finished = executor.awaitTermination(1, TimeUnit.MINUTES);
    System.out.println(finished ? "All tasks finished" : "Wait timed out");
  }
}

Output illustrativo di una singola esecuzione; l’ordine delle attività e gli ID numerici dipendono dal runtime:

Task 2 ran on worker ID 13
Task 3 ran on worker ID 13
Task 4 ran on worker ID 13
Task 5 ran on worker ID 13
Task 1 ran on worker ID 12
All tasks finished

Inserisci la chiamata all’interno dell’attività quando vuoi identificare il worker che la esegue. Se la chiami altrove, ottieni l’ID del thread che sta eseguendo quell’altro codice. Poiché un pool può riutilizzare i worker e pianificare le attività in modo diverso, considera l’output come rappresentativo di una singola esecuzione, non come una corrispondenza fissa tra numeri di attività e ID dei worker.