Thread.onSpinWait() 메서드는 Java 9에서 새롭게 도입된 기능입니다. Thread 클래스의 정적(static) 메서드로, 바쁜 대기(busy-waiting) 루프 안에서 선택적으로 호출할 수 있습니다.
이 메서드를 호출하면 JVM이 시스템 아키텍처에 따라 특수한 프로세서 명령어를 실행하여 스핀 대기(spin-wait) 루프의 반응 속도를 개선하고, 해당 코어 스레드가 소비하는 전력을 절감할 수 있습니다. 결과적으로 자바 프로그램 전체의 전력 효율이 향상되며, 동일한 전력 소비 범위 안에서 다른 코어 스레드들이 더 빠르게 실행될 수 있는 여유가 생깁니다.
참고로 내부적으로 이 메서드는 x86 아키텍처에서는 PAUSE 명령어에, ARM 아키텍처에서는 YIELD 명령어에 매핑되어 CPU에게 현재 스핀 루프 중임을 알려줍니다. 순수 자바 코드만으로는 성능 차이가 크지 않을 수 있지만, JIT 컴파일러가 이를 인식하면 하드웨어 수준의 최적화가 적용됩니다.
문법(Syntax)
public static void onSpinWait()
예제 코드
public class ThreadOnSpinWaitTest {
public static void main(final String args[]) throws InterruptedException {
final NormalTask task1 = new NormalTask();
final SpinWaitTask task2 = new SpinWaitTask();
final Thread thread1 = new Thread(task1);
thread1.start();
final Thread thread2 = new Thread(task2);
thread2.start();
new Thread(() -> {
try {
Thread.sleep(1000);
} catch(final InterruptedException e) {
e.printStackTrace();
} finally {
task1.start();
task2.start();
}
}).start();
thread1.join();
thread2.join();
}
private abstract static class Task implements Runnable {
volatile boolean canStart;
void start() {
this.canStart = true;
}
}
private static class NormalTask extends Task {
@Override
public void run() {
while(!this.canStart) {
}
System.out.println("Done!");
}
}
private static class SpinWaitTask extends Task {
@Override
public void run() {
while(!this.canStart) {
Thread.onSpinWait();
}
System.out.println("Done!");
}
}
}위 예제에서 NormalTask는 조건 검사 외에 아무 작업도 하지 않는 일반적인 스핀 루프를 사용하는 반면, SpinWaitTask는 루프 안에서 Thread.onSpinWait()를 호출합니다. 두 스레드 모두 1초 후 시작 신호를 받으면 "Done!"을 출력합니다.
실행 결과
Done! Done!
핵심 정리
- 도입 버전: Java 9부터 지원
- 메서드 유형: Thread 클래스의 정적(static) 메서드
- 주요 용도: busy-waiting(스핀 대기) 루프 내 최적화 힌트 제공
- 장점: 반응 속도 개선, 전력 소비 감소, 전체 시스템 효율 향상