HOWTO · Java
Java에서 스레드 ID 가져 오기
이 기사는 Java에서 스레드 ID를 가져 오는 방법을 살펴 봅니다.
이 페이지의 내용
Java에서는 Thread 객체에 Thread.getId()를 호출해 해당 스레드의 식별자를 읽을 수 있습니다. executor에서 작업이 실행되는 동안 Thread.currentThread().getId()를 호출하면 그 작업을 실행 중인 워커 스레드를 식별할 수 있습니다. 아래 예제는 두 경우를 모두 보여 줍니다. 두 값 모두 스레드 풀이나 스레드 이름을 식별하지는 않습니다. 이미 Thread 참조가 있다면 첫 번째 방법을 사용하고, 작업 안에서 현재 워커를 확인하려면 두 번째 방법을 사용하세요.
Java에서 Thread.getId()로 스레드 ID 가져오기
Thread 객체를 만든 다음 getId() 메서드를 호출하면 해당 객체의 식별자를 long 값으로 가져올 수 있습니다. 첫 번째 예제는 스레드 객체 두 개를 만들고 각각의 ID를 읽습니다. 스레드를 시작하지는 않습니다. 객체의 식별자를 읽는 데 스레드를 시작할 필요는 없습니다. 식별자 값은 런타임에서 할당되므로 실행할 때마다 또는 환경에 따라 달라질 수 있습니다. 따라서 예제의 숫자를 기준으로 삼지 말고 실행 중 반환된 값을 사용하세요. 특정 Thread 참조가 있고 그 객체를 다른 객체와 구분해야 할 때 유용합니다.
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());
}
}
한 번 실행했을 때의 예시 출력입니다. 출력 블록의 레이블은 코드와 출력의 원본 바이트를 유지하기 위해 영어로 표시됩니다.
Thread 1 ID: 12
Thread 2 ID: 13
위의 숫자 ID는 예시이며 런타임에 따라 달라집니다. 스레드를 시작하지 않았으므로 프로그램은 print 문에 적힌 순서대로 두 객체의 ID를 출력합니다. 다른 실행이나 환경에서도 같은 숫자가 나온다고 보장되지는 않습니다.
스레드 풀에서 현재 워커 스레드 ID 가져오기: Thread.currentThread().getId()
executor에 제출한 작업은 워커 스레드 중 하나에서 실행됩니다. 작업 내부에서 Thread.currentThread().getId()를 호출하면 현재 작업을 실행하는 워커의 ID를 가져올 수 있습니다. 이 값은 워커 ID이지 executor나 스레드 풀의 식별자가 아닙니다. 고정 스레드 풀은 워커를 재사용하므로 서로 다른 작업에서 같은 워커 ID가 반환될 수 있습니다. 어떤 워커가 각 작업을 처리할지는 스케줄링에 따라 달라지며, 작업 순서와 숫자 ID도 달라질 수 있습니다. 어떤 스레드가 특정 작업을 수행했는지 진단할 때 이 구분이 중요합니다. 반환된 숫자는 작업을 예약한 executor가 아니라 그 시점에 작업을 실행 중인 워커를 나타냅니다.
예제는 작업 다섯 개를 제출하고 각 작업 번호와 워커 ID를 출력한 다음 executor를 종료합니다. shutdown()은 새 작업을 받지 않도록 하면서 이미 제출된 작업은 완료되게 합니다. awaitTermination은 바쁜 대기 없이 완료될 때까지 최대 1분 기다립니다. 작업이 그보다 오래 걸리면 프로그램은 대기 시간 초과를 알립니다. 종료 요청은 이미 전달되었으므로 대기 중인 작업은 계속 실행될 수 있습니다. 실제 코드에서는 작업에 맞는 제한 시간을 정하고, 그 시간 안에 끝나지 않았을 때 어떻게 처리할지도 결정하세요. 특정 Java 릴리스에서 사용할 API 세부 사항을 정해야 한다면 해당 릴리스의 문서를 확인하세요. 여기서는 대상 릴리스를 지정하지 않았습니다.
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");
}
}
한 번 실행했을 때의 예시 출력입니다. 작업 순서와 숫자 ID는 런타임에 따라 달라지며, 출력 블록의 레이블은 원본 바이트를 유지하기 위해 영어로 표시됩니다.
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
목표가 작업을 실행하는 워커를 식별하는 것이라면 작업 내부에서 이 메서드를 호출하세요. 다른 위치에서 호출하면 그 코드를 실행하는 스레드가 반환됩니다. 스레드 풀은 워커를 재사용하고 작업을 다른 순서로 스케줄링할 수 있으므로, 출력은 한 번의 실행 결과로만 이해하고 작업 번호와 워커 ID가 항상 고정된 관계라고 보지 마세요.