"안녕, 아미고!

"모든 새로운 것은 우리가 잊어버린 오래된 것일 뿐입니다. 오늘은 스레드 중지에 대해 이야기하겠습니다. 당신이 이미 인터럽트() 메서드가 작동하는 방식을 잊어버렸기를 바랍니다."

"네, 엘리, 완전히 잊어버렸어요."

"좋아. 그럼 내가 상기시켜줄게."

"자바에서 누군가 실행 중인 스레드를 중지하려는 경우 스레드에 신호를 보낼 수 있습니다. 이렇게 하려면 스레드 개체의 숨겨진 isInterrupted 변수 를 true로 설정해야 합니다."

"각 스레드에는 이 플래그를 설정하는 데 사용되는 인터럽트() 메서드가 있습니다. 인터럽트 () 메서드가 호출 되면 스레드 개체 내부의 isInterrupted 변수가 true로 설정됩니다."

"Thread.sleep() 또는 join() 메서드가 스레드에서 호출되면 메서드는 isInterrupted 플래그가 현재 스레드에 대해 설정되어 있는지 확인합니다. 이 플래그가 설정되면(isInterrupted 변수가 true와 같음) 메서드InterruptedException 을 던집니다 ."

"여기에서 오래된 예를 상기시켜 드리겠습니다."

암호 설명
class Clock implements Runnable
{
public void run()
{
Thread current = Thread.currentThread();

while (!current.isInterrupted())
{
Thread.sleep(1000);
System.out.println("Tik");
}
}
}
Clock의 run 메서드는 현재 스레드에 대한 Thread 개체를 가져옵니다.

Clock 클래스는 현재 스레드의 isInterrupt 변수가 false인 한 초당 한 번씩 "Tick"이라는 단어를 콘솔에 씁니다.

isInterrupt가 true가 되면 run 메서드가 종료됩니다.

public static void main(String[] args)
{
Clock clock = new Clock();
Thread clockThread = new Thread(clock);
clockThread.start();

Thread.sleep(10000);
clockThread.interrupt();
}
메인 스레드는 영원히 실행되어야 하는 하위 스레드(시계)를 시작합니다.

10초를 기다린 후 인터럽트 메서드를 호출하여 작업을 취소합니다.

기본 스레드가 작업을 완료합니다.

클럭 스레드가 작업을 완료합니다.

"여기서 우리는 run 메서드 에서 무한 루프의 일부로 sleep 메서드를 사용합니다 . 루프에서 isInterrupt 변수는 자동으로 검사됩니다. 스레드가 sleep 메서드를 호출하면 메서드는 먼저 해당 스레드에 대해 isInterrupt 가 참인지 확인합니다( sleep 메서드를 호출한 것). 이것이 참이면 메서드는 잠들지 않습니다. 대신 InterruptedException 을 발생시킵니다 . "

"하지만 이 예에서는 루프 조건에서 isInterrupted 변수를 지속적으로 확인합니다."

"이 접근법을 사용할 수 없는 몇 가지 이유가 있었던 것으로 기억합니다. 상기시켜 주시겠습니까?"

" 첫째 , run 메서드에 항상 루프가 있는 것은 아닙니다. 이 메서드는 단순히 다른 메서드에 대한 수십 번의 호출로 구성될 수 있습니다. 이 경우 각 메서드 호출 전에 isInterrupted 검사를 추가해야 합니다."

" 둘째 , 다양한 작업이 많이 포함된 일부 메서드는 실행하는 데 시간이 오래 걸릴 수 있습니다."

" 셋째 , 예외 발생은 isInterrupted 검사를 대체하지 않습니다. 단지 편리한 추가 기능일 뿐입니다. 발생된 예외를 사용하면 호출 스택을 run 메서드 자체 로 빠르게 되돌려 놓을 수 있습니다. "

" 넷째 , 수면 방법이 많이 사용됩니다. 이 유용한 방법은 그다지 도움이 되지 않는 암묵적 확인으로 향상되는 것으로 나타났습니다. 마치  아무도 특별히 확인을 추가하지 않은 것처럼 보이지만, 거기에 있습니다.  이것은 당신이 할 때 매우 가치가 있습니다. 다른 사람의 코드를 사용하고 있고 직접 확인을 추가할 수 없습니다."

" 다섯째 , 추가 검사는 성능을 저하시키지 않습니다. sleep 메서드를 호출한다는 것은 스레드가 아무 작업도 수행하지 않아야 함을 의미하므로(수면 제외) 추가 작업으로 인해 아무도 귀찮게 하지 않습니다."

"그게 바로 당신이 이전에 말했던 것입니다."

"그러면 « 아무도 스레드가 중지될 것이라고 보장할 수 없습니다. 스레드만 자체적으로 중지할 수 있습니다. » 설명할 수 있습니까?"

"확신하는."

"이전에는 Java의 초기 버전에서 스레드에 stop() 메서드가 있었습니다. 그리고 이 메서드를 호출하면 JVM이 실제로 스레드를 중지했습니다. 하지만 스레드가 JVM 외부에서 작업(예: 파일에 쓰기 또는 호출)을 수행하는 경우 OS 기능) 이런 식으로 중단되었을 때 중단으로 인해 파일이 닫히지 않거나 시스템 리소스가 해제되지 않는 등 많은 문제가 발생했습니다."

"자바 창시자 총회에서 쓰레드 강제 종료 방법을 삭제하기로 결정했습니다. 이제 우리가 할 수 있는 일은 특정 플래그(isInterrupted)를 설정하고 스레드 코드가 올바르게 작성되어 이 플래그가 처리되기를 바라는 것뿐입니다. 이 플래그는 매우 중요합니다!'라는 표지판과 같습니다. 하지만 멈추거나 말거나는 각자의 일입니다."

"하지만 InterruptedException은 어떻습니까?"

"이 스레드에서 실행 중인 코드에 여러 개의 try-catch 블록이 있으면 어떻게 됩니까? 어딘가에서 InterruptedException이 발생하더라도 일부 try-catch가 이를 포착하고 잊어버리지 않는다는 보장은 없습니다. 스레드가 중지됩니다."

"또 다른 것은 스레드가 이미 상당히 저수준 프로그래밍으로 간주된다는 것입니다. 하지만 다음에 그것에 대해 말씀 드리겠습니다."

"당신은 Ellie가 아닙니다. 당신은 Scheherazade입니다!"

"그래서, 아미고! 현재 수업은 모두 명확합니까?"

"네."

"좋아, 좋아."