HOWTO · Java

Thread-ID in Java abrufen

In diesem Artikel werden die Methoden zum Abrufen der Thread-ID in Java vorgestellt.

Auf dieser Seite

Rufen Sie in Java Thread.getId() für ein Thread-Objekt auf, um dessen Kennung auszulesen. Während eine Aufgabe in einem Executor läuft, gibt Thread.currentThread().getId() die Kennung des Worker-Threads zurück, der sie gerade ausführt. Die folgenden Beispiele zeigen beide Fälle; keiner der beiden Werte bezeichnet einen Thread-Pool oder einen Thread-Namen. Verwenden Sie den ersten Ansatz, wenn Sie bereits eine Referenz auf ein Thread-Objekt haben, und den zweiten innerhalb einer Aufgabe, wenn Sie den dort gerade ausführenden Worker ermitteln möchten.

Eine Thread-ID in Java mit Thread.getId() ermitteln

Erzeugen Sie ein Thread-Objekt und rufen Sie dann dessen Methode getId() auf, um die Kennung dieses Objekts als long abzurufen. Das erste Beispiel erzeugt zwei Thread-Objekte und liest beide IDs aus. Es startet die Threads nicht; das ist nicht nötig, um die Kennungen dieser Objekte auszulesen. Die Laufzeitumgebung weist die Kennungen zu, und sie können sich je nach Ausführung oder Umgebung unterscheiden. Verwenden Sie daher den zur Laufzeit zurückgegebenen Wert, statt sich auf Beispielwerte zu verlassen. Das ist hilfreich, wenn der Code eine Referenz auf einen bestimmten Thread hat und dieses Objekt von einem anderen unterscheiden muss.

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

Beispielhafte Ausgabe eines Durchlaufs:

Thread 1 ID: 12
Thread 2 ID: 13

Die Zahlen-IDs oben dienen nur zur Veranschaulichung und hängen von der Laufzeitumgebung ab. Da die Threads nicht gestartet werden, gibt das Programm die IDs der beiden Objekte in der Reihenfolge der Druckanweisungen aus. Die Beispielwerte sind bei einem anderen Durchlauf oder in einer anderen Umgebung nicht garantiert. Die Ausgabebezeichnungen im unveränderten Beispiel bleiben englisch.

Die ID des aktuellen Worker-Threads in einem Thread-Pool mit Thread.currentThread().getId() ermitteln

Eine an einen Executor übermittelte Aufgabe läuft auf einem seiner Worker-Threads. Rufen Sie innerhalb der Aufgabe Thread.currentThread().getId() auf, um die ID des Workers zu erhalten, der sie gerade ausführt. Dieser Wert ist die ID eines Worker-Threads und keine Kennung des Executors oder des Pools. Ein fester Pool verwendet seine Worker wieder, daher können verschiedene Aufgaben dieselbe Worker-ID melden. Die Planung bestimmt, welcher Worker welche Aufgabe übernimmt; sowohl die Aufgabenreihenfolge als auch die Zahlen-IDs können variieren. Diese Unterscheidung ist wichtig, wenn Sie nachvollziehen möchten, welcher Thread eine Arbeitseinheit ausgeführt hat: Die zurückgegebene Zahl beschreibt den gerade ausführenden Worker, nicht den Executor, der die Aufgabe eingeplant hat.

Das Beispiel übermittelt fünf Aufgaben, gibt für jede Aufgabennummer und die ID ihres Worker-Threads aus und fährt anschließend den Executor herunter. shutdown() verhindert, dass der Executor neue Aufgaben annimmt, lässt aber bereits übermittelte Aufgaben abschließen. awaitTermination wartet bis zu einer Minute auf den Abschluss, ohne in einer Warteschleife ständig aktiv zu prüfen. Dauert die Arbeit länger, meldet das Programm, dass die Wartezeit abgelaufen ist. Die Herunterfahranforderung wurde bereits gestellt, daher können Aufgaben in der Warteschlange weiterlaufen. Wählen Sie im Produktivcode eine Zeitbegrenzung, die zur Arbeit der Anwendung passt, und legen Sie fest, wie die Anwendung reagiert, wenn Aufgaben nicht rechtzeitig fertig werden. Wenn Sie API-Details für eine bestimmte Java-Version auswählen müssen, lesen Sie die Dokumentation zu dieser Version; hier ist keine Zielversion angegeben.

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

Beispielhafte Ausgabe eines Durchlaufs; Aufgabenreihenfolge und Zahlen-IDs hängen von der Laufzeitumgebung ab:

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

Rufen Sie die Methode innerhalb der Aufgabe auf, wenn Sie den Worker ermitteln möchten, der diese Aufgabe ausführt. An anderer Stelle aufgerufen, liefert sie die ID des Threads, der den dortigen Code ausführt. Da ein Pool Worker wiederverwenden und Aufgaben unterschiedlich einplanen kann, dient die Ausgabe dazu, einen einzelnen Durchlauf nachzuvollziehen; sie ist keine feste Zuordnung zwischen Aufgabennummern und Worker-IDs. Die Ausgabebezeichnungen im unveränderten Beispiel bleiben englisch.