Java 스레드 인터럽트 및 LockSupport 동기화

스레드 인터럽트 메커니즘

Java에서 스레드는 외부에서 강제로 중지되지 않으며 자발적으로 중단해야 합니다. Thread.stop()과 같은 메서드는 폐기되었으며, 대신 협력적 인터럽트 메커니즘이 도입되었습니다. 스레드 객체의 interrupt() 호출은 인터럽트 플래그를 설정하고, 대상 스레드가 이 상태를 주기적으로 확인하여 작업을 종료합니다.

인터럽트 API 메서드

  • void interrupt() : 스레드의 인터럽트 상태 설정
  • boolean isInterrupted() : 스레드의 인터럽트 상태 확인 (상태 변경 없음)
  • static boolean interrupted() : 현재 스레드의 인터럽트 상태 반환 후 초기화

실행 중인 스레드 중지 방법

volatile 변수 활용:

public class InterruptExample {
    private static volatile boolean stopRequested = false;

    public static void main(String[] args) {
        new Thread(() -> {
            while (!stopRequested) {
                System.out.println("실행 중");
            }
            System.out.println("종료: 플래그 변경 감지");
        }).start();

        new Thread(() -> {
            try { Thread.sleep(20); } 
            catch (InterruptedException e) {}
            stopRequested = true;
        }).start();
    }
}

AtomicBoolean 활용:

public class AtomicInterrupt {
    private static final AtomicBoolean atomicFlag = new AtomicBoolean(false);

    public static void main(String[] args) {
        new Thread(() -> {
            while (!atomicFlag.get()) {
                System.out.println("동작 중");
            }
            System.out.println("중단: 원자적 플래그 변경");
        }).start();

        new Thread(() -> {
            try { Thread.sleep(20); } 
            catch (InterruptedException e) {}
            atomicFlag.set(true);
        }).start();
    }
}

인터럽트 API 직접 사용:

public class DirectInterrupt {
    public static void main(String[] args) {
        Thread worker = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("작업 수행");
            }
            System.out.println("인터럽트 감지");
        });
        worker.start();

        new Thread(() -> {
            try { Thread.sleep(20); } 
            catch (InterruptedException e) {}
            worker.interrupt();
        }).start();
    }
}

인터럽트 주의사항

sleep() 중 인터럽트 발생 시:

public class SleepInterrupt {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    Thread.sleep(200);
                    System.out.println("작업 계속");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt(); // 플래그 재설정
                }
            }
            System.out.println("정상 종료");
        });
        t.start();
        t.interrupt();
    }
}

LockSupport 동기화

LockSupport는 스레드 블로킹 기본 구현체로, park()과 unpark() 메서드를 제공합니다.

기본 사용법

import java.util.concurrent.locks.LockSupport;

public class ParkExample {
    public static void main(String[] args) {
        Thread worker = new Thread(() -> {
            System.out.println("진입");
            LockSupport.park();
            System.out.println("재개");
        });
        
        worker.start();
        LockSupport.unpark(worker); // 즉시 재개
    }
}

실행 순서 유연성

public class OrderExample {
    public static void main(String[] args) {
        Thread worker = new Thread(() -> {
            try { Thread.sleep(1000); } 
            catch (InterruptedException e) {}
            System.out.println("park 호출");
            LockSupport.park();
            System.out.println("실행 완료");
        });
        
        worker.start();
        LockSupport.unpark(worker); // 선행 unpark
    }
}

Permit 동작 원리

  • unpark(): permit 설정 (최대 1개)
  • park(): permit 소모 (있으면 통과, 없면 대기)
  • 중복 unpark()은 permit 누적되지 않음

태그: java 스레드 동기화 LockSupport 인터럽트

6월 8일 21:39에 게시됨