sitelink1 http://blog.naver.com/yusiky326/50172744138 
sitelink2  
sitelink3  
sitelink4  
sitelink5  
sitelink6  

문제점 #1: 

 

Thread.stop 메소드는 deprecated 되어버렸다.

 

안전하지 않다는 이유에서다.[1]

 

종료시키고자 하는 쓰레드가 Thread.stop을 통해 종료되게 되면 보유하고 있던 모니터들(monitors)을 전부 놓아(unlock)버리게 되는데, 이들에 의해 보호받고 있던 오브젝트들이 더이상 보호를 받지 못해 문제가 발생한다.  해당 오브젝트들이 일관적이지 않은 상태가 되면 보통 데미지를 받은(damaged) 상태라고 하는데 이 상태에서는 예상치 못한 결과가 나올 수 있다.  감지하기도 쉽지 않다. :(

 

심지어 ThreadDeath(?)는 쓰레드를 암살(?)해버려서 어떠한 경고도 사용자에게 주지 않는다.

 

해결책 #1: 

구글을 뒤져보니 다음과 같은 방법이 있었다.[2]

쓰레드 종료를 원할 때 특정 시나리오(주기적으로 같은 것을 실행하는 쓰레드)에서 변수 하나를 주어 계속 감지하는 것이다.  일단 진행하고자 했던 코드는 이 시나리오에 해당되기에 무사히 넘어갈 수 있었다.

 

public class AlarmRunnable implements Runnable {

    private volatile boolean running = true;

 

    public void terminate() {

        running = false;

    }

 

    @override

    public void run() {

        while(running) {

            try {

                Thread.sleep((long) 10000);

            } catch (InterruptedException e) {

                running = false;

            }

        }

    }

}

 

위 코드를 살펴보면 사용자가 원할 때 terminate() 메소드를 호출할 경우 running값이 false가 되어 run()메소드 내부의 반복문 while이 종료될 것이다.

또한, 원치 않는 exception이 발생했을 때도 마찬가지로 running값이 false가 되서 종료된다.

 

이제 이를 적용시키는 클래스 예를 들면

public class HelloThread {

    private Thread alarmThread = null;

    private AlarmRunnable alarmRunnable= null;

 

    public void alarmInitiate() {

        alarmRunnable = new AlarmRunnable();

        alarmThread = new Thread(alarmRunnable);

        alarmThread.start();

    }

 

    public void alarmTerminate() {

        if (alarmThread != null) {

            alarmRunnable.terminate();

            alarmThread.join();

        }

    }

}

 

대략 이런 느낌이다.

 

만약에 위의 코드처럼 10초마다 running 변수를 감지할 수 있는 형태가 아닌 시나리오라면 어떨까?

 

위의 방법을 쓰면 10초 주기로 running 변수를 확인해야하는 부분 때문에 CPU 사이클을 낭비하게 된다.

주기를 10초보다 짧게 주면 더 많은 CPU 사이클의 낭비를, 길게 주면 종료 처리까지 기다리는 시간이 길어진다.

따라서 다음과 같은 방법을 또 찾게 되었다.[3]

 

해결책 #2:  

Thread.interrupt() 메소드를 쓰면 InterruptedException이 발생되어 익셉션 처리 코드로 넘어가게 된다.

이 익셉션을 이용하여 쓰레드 종료에 필요한 정리를 하는 것이다.

참고로 InterruptedException을 발생시키는 것은

interrupt() 호출 시점에 Object 클래스의 wait(), wait(long), wait(long, int)나 

Thread 클래스의 join(), join(long), join(long, int), sleep(long), sleep(long, int)메소드가 호출될 경우이다. [3]

 

 다음은 run() 메소드를 오버라이드하여 InterruptedException이 감지되었을 때 쓰레드를 종료시키도록 유도하는 코드의 예이다.  alarmRunnable과 alarmThread는 스태틱(static) 전역(global) 변수로 각각 Runnable, Thread 타입이다.

public class AlarmRunnable implements Runnable {

    @Override

    public void run() {

        try {

            Thread.sleep(60000);

        } catch (InterruptedException e) {

        } finally {

            alarmRunnable = null;

            alarmThread = null;

        }

    }

}

 

이를 이용하여 Thread를 종료시키려면 다음과 같이 하면 된다.

private void killAlarmThread() {

    try {

        alarmThread.interrupt();

        alarmThread.join();

    } catch(InterruptedException e) {

        e.printStackTrace();

    }

}

alarmThread.interrupt();가 실행 되면 잠자고있던(또는 실행하고 있던) 쓰레드가 이를 감지하여 catch(InterruptedException e) 실행부분으로 넘어가고, 위의 코드에서는 catch()에서 실행하는 것이 업서서 finally() 실행부분으로 넘어가면 다 실행되면 쓰레드는 종료된다.

 

alarmThread가 살아있을 때에만 강제 종료처리가 이루어지도록 불러보았다.

 ...

if (alarmRunnable != null && alarmThread != null) {

    killAlarmThread();

}

 ...

 

Reference

[1] http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html

[2] http://stackoverflow.com/questions/10961714/how-to-properly-stop-the-thread-in-java

[3] http://baeksupervisor.tistory.com/31

[출처] Java: 쓰레드(Thread)를 중간에 종료시키는 방법|작성자 제오

번호 제목 글쓴이 날짜 조회 수
251 Calendar, Date, Format, java.time 패키지 황제낙엽 2017.10.31 108
250 날짜, 시간 문자열 값으로 Date 오브젝트로 만들기 >> SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.US) 황제낙엽 2017.10.31 1516
249 시스템 속성(System Property) 클래스를 이용하여 jni 라이브러리 사용하기 황제낙엽 2017.09.22 37
248 Java 실행 옵션들 황제낙엽 2017.08.23 3367
247 HttpsURLConnection 을 사용한 SSL서버 접속 file 황제낙엽 2017.08.02 231
246 서버구동시 주기적으로 동작을 수행하는 스레드를 함께 실행하는 서블릿 황제낙엽 2017.08.02 131
245 HttpURLConnection 사용 샘플( JSP , SERVLET ) 황제낙엽 2017.08.01 254
244 HttpURLConnection 사용하기 황제낙엽 2017.08.01 393
243 [HttpURLConnection] POST로 파라미터 넘기기 황제낙엽 2017.08.01 507
242 HttpURLConnection POST 방식 사용하기 황제낙엽 2017.08.01 370
241 Runtime 클래스를 이용한 윈도우 프로그램 실행 예제 황제낙엽 2017.08.01 113
240 JSON Util (JSON 을 다루기 위해 직접 작성한 유틸 클래스) file 황제낙엽 2017.07.10 461
239 자바 리플렉션(Java Reflection) 간단한 설명 및 사용방법 정리 file 황제낙엽 2017.07.10 135
238 Generate random numbers (Random.java) 황제낙엽 2017.07.02 490
» 쓰레드(Thread)를 중간에 종료시키는 방법 황제낙엽 2017.03.15 5127
236 JSON 라이브러리(API) 종류 황제낙엽 2017.01.18 404
235 [JSON기초04] 자바 JSON 데이터에서 KEY 값 알아오기 (TIP) 황제낙엽 2017.01.18 6641
234 [JSON기초03] 자바 JSON Google Simple JSON을 이용한 간단한 JSON DATA 파싱 황제낙엽 2017.01.18 566
233 [JSON기초02] 자바 JSON Google Simple JSON을 이용한 간단한 JSON DATA 생성 황제낙엽 2017.01.18 111
232 [JSON기초01] JSON이란? XML이란? JSON 개념, XML 개념 설명 황제낙엽 2017.01.18 408