HOWTO · Java

How to Get a Thread ID in Java

Learn how to get a Java thread ID with `Thread.getId()` and identify the worker running an executor task with `Thread.currentThread().getId()`.

On this page

In Java, call Thread.getId() on a Thread object to read that thread’s identifier. While a task is running in an executor, Thread.currentThread().getId() identifies the worker thread executing it. The examples below show both cases; neither value identifies a thread pool or a thread name. Use the first approach when you already have a Thread reference, and use the second from code running inside a task when you need to identify its current worker.

Get a Thread ID in Java with Thread.getId()

Create a Thread object, then call its getId() method to retrieve that object’s identifier as a long. The first example creates two thread objects and reads both IDs. It does not start the threads; starting them is not needed to read the identifiers from these objects. The identifier values are assigned by the runtime and can differ between runs or environments, so use the returned value at runtime instead of relying on sample numbers. This is useful when code has a reference to a particular Thread and needs to distinguish that object from another one.

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

Illustrative output from one run:

Thread 1 ID: 12
Thread 2 ID: 13

The numeric IDs above are illustrative and runtime-dependent. Because the threads are not started, the program prints the two object IDs in the order of the print statements; the sample numbers are not guaranteed in another run or environment.

Get the Current Worker Thread ID in a Thread Pool with Thread.currentThread().getId()

A task submitted to an executor runs on one of its worker threads. Call Thread.currentThread().getId() from inside the task to get the ID of the worker currently running it. This is a worker ID, not an identity for the executor or the pool. A fixed pool reuses its workers, so different tasks may report the same worker ID. Scheduling determines which worker handles each task, and both the task order and numeric IDs may vary. This distinction matters when diagnosing which thread performed a unit of work: the returned number describes the executing worker at that moment, rather than the executor that scheduled it.

The example submits five tasks, prints each task number and its worker ID, then shuts down the executor. shutdown() stops it from accepting new tasks while allowing submitted tasks to complete. awaitTermination waits for completion for up to one minute without busy-spinning. If work takes longer than that, the program reports that the wait timed out; the shutdown request has already been made, so queued work can continue. For production code, choose a timeout that fits the application’s work and decide how it should respond if tasks do not finish in time. If you need to choose API details for a particular Java release, consult the documentation for that release; no target release is specified here.

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

Illustrative output from one run; task order and numeric IDs are runtime-dependent:

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

Place the call inside the task when your goal is to identify the worker executing that task. Calling it elsewhere reports the thread running that other code. Because a pool can reuse workers and schedule tasks differently, use the output to understand one run rather than as a fixed mapping between task numbers and worker IDs.