JAVA - 쓰레드 stop()메소드
■ Thread의 Deprecated Method. stop()
Thread는 자신의 run() 메소드가 모두 실행되면 자동적으로 종료된다. 하지만, 경우에 따라서 개발자는 실행 중인 스레드를 즉시 종료할 필요가 있다. 예를 들어 동영상을 끝까지 보지 않고, 사용자가 멈춤을 요구하는 경우가 이에 해당한다. Thread는 스레드를 즉시 종료시키기 위해서 stop() 메소드를 제공하고 있는데, 이 메소드는 deprecated 되었다. 이유가 뭘까?
Oracle이 제공하는 JAVA API 문서를 보면 Deprecated. This method is inherently unsafe. 를 시작으로 이 메소드가 사라진 자세한 이유가 쓰여져 있다. 이유는 간단히 말해 stop() 메소드로 스레드를 갑자기 종료하게 되면, 스레드가 사용중이던 자원들이 불안전한 상태로 남겨지기 때문이다. 자세한 설명은 oracle 공식 사이트에서 제공하는 java document 중 Java Thread Primitive Deprecation 이라는 제목으로 제공되는 문서를 참고하면 된다.
Thread의 stop() 안전하게 이용할 수 있는 방법 중 하나는, 스레드의 run() 메소드가 정상적으로 종료 되도록 유도하는 것이다. 아래와 같이 스레드의 마지막 부분에서 플래그의 값을 변경하는 작업을 통해서 스레드가 정상적으로 종료 될 수 있도록 유도하는 것이 최선의 방법이다.
■ Thread의 interrupt() 메소드
Thread의 interrupt() 메소드는 스레드가 일시 정지 상태에 있을 때 InterruptedException 예외를 발생시키는 역할을 한다. 이것을 이용하면 Thread의 run() 메소드를 정상 종료시킬 수 있다.
사용법은 아래와 같다. main 메소드에서 thread의 interrupt() 메소드를 실행하게 되면 thread가 sleep() 메소드로 일시 정지 상태가 될 때 thread 에서 InterruptedException이 발생하여 예외 처리(catch)블록으로 이동한다. 결국 thread는 while문을 빠져나와서 run() 메소드를 정상 종료하게 된다. 아래의 코드에서는 thread가 시작한 후 1초 뒤에 InterruptedException이 발생하여 thread를 멈추도록 interrupt() 메소드를 호출한다.
* Thread의 stop() 메서드를 호출하면 쓰레드가 바로 멈춘다.
* 이때 사용하던 자원을 정리하지 못하고 프로그램이 종료되서
* 나중에 실행되는 프로그램에 영향을 줄 수 있다.
* 그래서 현재는 stop()메서드는 비추천(deprecated) 되어있다.
public class T13_ThreadStopTest {
public static void main(String[] args) {
ThreadStopEx1 th = new ThreadStopEx1();
//th.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//th.stop(); 비추천
//th.setStop(true);//추천
//interrupt()메서드를 이용한 쓰레드 멈추기
ThreadStopEx2 th2 = new ThreadStopEx2();
th2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
th2.interrupt();
}
}
class ThreadStopEx1 extends Thread{
private boolean stop;
public void setStop(boolean stop) {
this.stop = stop;
}
@Override
public void run() {
while (!stop) {
System.out.println("쓰레드 처리중 ...");
}
System.out.println("자원 정리중 ...");
System.out.println("실행 종료.");
}
}
/**
* interrupt()메서드를 이용하여 쓰래드를 멈추게하는 방법
*/
class ThreadStopEx2 extends Thread{
@Override
public void run() {
/*
*
* 방법1. => sleep()메서드나 join()메서드 등을 사용했을 때
* interrupt()메서드를 호출하면 InterruptedException이 발생한다
try {
while (true) {
System.out.println("쓰레드 처리중 .....");
Thread.sleep(1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
*/
/*
* 방법2. => interrupt()메서드가 호출되었는지 검사하기
*/
while (true) {
System.out.println("쓰래드 처리중 ");
/*//검사 방법 1=> interrupt()메서드가 호출되었는지 검사하기
if(this.isInterrupted()) {//interrupt()메서드가 호출되면 true
System.out.println("인스턴스용 isInterrupted()");
break;
}*/
//검사방법2=> 쓰레드의 정적 메서드를 이용하는 바업
if(Thread.interrupted()) {//interrupt()메서드가 호출되면 true
System.out.println("인스턴스용 interrupted()");
break;
}
}
System.out.println("자원 정리 중 ...");
System.out.println("실행 종료");
}
}