본문 바로가기
Java

[Java] Thread 종료하는 방법, interrupt() 메서드 동작 방식

by doogfoot 2024. 11. 5.

 

필요성

 

Java를 개발하다 보면 Thread를 생성하고 라이프사이클을 제어해야 되는 경우가 많습니다

 

일반적으로 스레드는 현재 실행 중인 작업(run 메서드)이 다 끝나면 자동으로 종료됩니다

 

만약 실행중인 작업을 다 끝나기 전에 스레드를 종료하고 싶다면 어떻게 해야 될까요?

 

혹은 작업이 너무 오래 걸리거나 무한 루프를 돌고 있어서, 스레드를 강제 종료시켜야 하는 경우도 있을 수 있습니다.

 

 

정의

 

Thread의 interrupt() 메서드는 스레드를 중간에 종료시킬 수 있는 메서드입니다. 

 

여기서 중요한 점은 interrup() 메서드를 호출한다고 해서 모든 상황에서 스레드가 종료되는 건 아닙니다

 

우선 interrupt 메서드를 호출하면 일시 정지(WAITING, TIMED_WAITING) 상태의 스레드를 깨워서 RUNNABLE 상태로 변경됩니다.

 

 

 

동작 방식 

 

Thread 가 sleep, wait, join 등을 통해 일시 정지 상태에 있을 때, interrupt 메서드를 호출하면 InterruptedException 예외를 발생시켜 run() 메서드를 종료시킬 수 있습니다. 

 

위에서 말한것처럼 스레드가 RUNNABLE 상태가 되어야 try catch 구문에서 예외 코드가 실행될 수 있습니다

 

만약 일시 정지 상태가 아니라면 interrupt() 메서드를 호출해도 그 즉시는 아무 일도 일어나지 않습니다.

 

현재 일시 정지 상태가 아니더라도 미래에 일시정지 상태가 될 때 똑같이 InterruptedException 예외가 발생됩니다

 

 

 

 

여기에 이어서 궁금한 점이 생겨야 합니다.

 

바로 interrupt 메서드를 호출했을 때 예외가 발생할지, 아니면 interrupt 상태가 아니어서 예외를 발생시키지 않을지를 코드로 알 수 있어야 합니다. 

 

즉, interrupt 상태를 알 수 있는 방법에 대해서 설명드리겠습니다.

Thread.interrupted()
thread.isInterrupted()

interrupted() 정적 메서드를 호출하면 interrupt 상태를 boolean 타입으로 반환하고, interrupt 상태를 false로 변경합니다.

 

반면 스레드 인스턴스의 isInterrupted() 메서드를 호출하면 상태 변경 없이 현재 상태를 반환합니다.

 

가장 앞에서 설명한 interrupt 메서드는 단지 스레드의 interrupt 상태를 false에서 true로 변경한다고 생각하면 쉽습니다

 

 

 

아래는 interrupt, isInterrupted 메서드를 활용한 예시입니다. 

public class InterruptExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            try {
                while (!Thread.currentThread().isInterrupted()) {
                    System.out.println("Running...");
                    Thread.sleep(1000); // sleep() 중 interrupt 발생 시 InterruptedException 발생
                }
            } catch (InterruptedException e) {
                System.out.println("Thread was interrupted during sleep.");
                // 인터럽트 상태를 초기화하거나, 필요시 다른 작업을 수행하고 종료할 수 있음
            }
            System.out.println("Thread exiting...");
        });

        thread.start();

        try {
            Thread.sleep(3000); // 메인 스레드가 3초 대기
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt(); // 만일 메인 스레드가 인터럽트되면 복구
        }

        thread.interrupt(); // 3초 후에 인터럽트 발생
    }
}

 

 

정리

 

스레드가 일시정지 상태일 때 interrupt 메서드를 사용하면 예외를 발생시킬 수 있습니다

 

예외를 통해 해당 스레드를 원하는 조건, 원하는 시점에 종료시킬 수 있습니다.

 

스레드의 상태, 라이프사이클에 대해서 알고 스레드와 관련된 개발을 진행하면 도움이 많이 될 것 같습니다.

댓글