스레드를 안전하고 빠르게 안정적으로 멈추게하는 것은 어려운 일이다

자바에는 스레드를 강제로 멈추도록 하는 방법이 없다. Thread.stop(), Thread.suspend() 매서드는 문제가 많아서 쓰면안됨 (deprecated됨)

대신 인터럽트를 사용하여 스레드에게 작업을 멈춰달라고 요청해야 한다. 강제 종료하면 비정상적인 상태에 놓이는 경우가 있기 때문에, 스레드 협력하여 작업을 멈추도록 해야한다

작업 중단의 Case

작업중단 방법

(1) 취소 flag를 이용한 통지

cancel 메서드랑 isCancelled(volatile 선언필요) 같은 변수를 사용하고, 스레드는 중간중간 취소 flag를 확인하여 취소 flag가 true일 경우 진행 중인 작업을 종료하는 방법

(2) 인터럽트

그러나 위의 취소flag를 이용한 종료에는 한계가 있다 스레드가 BlockingQueue.put() 와 같이 블러킹 메서드를 호출하여 블러킹 상태에 빠져있다면 취소 요청을 확인할 방법이 없다. 다시 말하면 영영 작업을 취소하지 못하는 상황이 생길 수도 있다.

모드 스레드는 boolean 값으로 인터럽트 상태를 갖고 있다. 스레드에 인터럽트가 걸리면 true 로 설정된다.

그러나 특정 스레드의 interrupt 메서드를 호출했다 하더라도 해당 스레드가 처리하던 작업을 멈추지 않는다.

해당 스레드에게 인터럽트 요청이 있었다는 메시지를 전달할 뿐, 작업 스레드는 isInterrupted() 메서드등을 사용하여 인터럽트를 확인하여 스레드가 처리해야한다.

public class PrimeProducer extends Thread {
    private final BlockingQueue<BigInteger> queue;
 
    PrimeProducer(BlockingQueue<BigInteger> queue) {
        this.queue = queue;
    }
 
    public void run() {
        try {
            BigInteger p = BigInteger.ONE;
            while (!Thread.currentThread().isInterrupted())         // 인터럽트르 확인
                queue.put(p = p.nextProbablePrime());
        } catch (InterruptedException consumed) {
            /* 스레드를 종료 */
        }
    }
 
    public void cancel() {
        interrupt();
    }
}