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)를 중간에 종료시키는 방법|작성자 제오

번호 제목 글쓴이 날짜 조회 수
243 [HttpURLConnection] POST로 파라미터 넘기기 황제낙엽 2017.08.01 873
242 HttpURLConnection POST 방식 사용하기 황제낙엽 2017.08.01 798
241 Runtime 클래스를 이용한 윈도우 프로그램 실행 예제 황제낙엽 2017.08.01 413
240 JSON Util (JSON 을 다루기 위해 직접 작성한 유틸 클래스) file 황제낙엽 2017.07.10 819
239 자바 리플렉션(Java Reflection) 간단한 설명 및 사용방법 정리 file 황제낙엽 2017.07.10 498
238 Generate random numbers (Random.java) 황제낙엽 2017.07.02 839
» 쓰레드(Thread)를 중간에 종료시키는 방법 황제낙엽 2017.03.15 5516
236 JSON 라이브러리(API) 종류 황제낙엽 2017.01.18 713
235 [JSON기초04] 자바 JSON 데이터에서 KEY 값 알아오기 (TIP) 황제낙엽 2017.01.18 7217
234 [JSON기초03] 자바 JSON Google Simple JSON을 이용한 간단한 JSON DATA 파싱 황제낙엽 2017.01.18 908
233 [JSON기초02] 자바 JSON Google Simple JSON을 이용한 간단한 JSON DATA 생성 황제낙엽 2017.01.18 462
232 [JSON기초01] JSON이란? XML이란? JSON 개념, XML 개념 설명 황제낙엽 2017.01.18 689
231 싱글톤 방식의 테스트용 Temporary Data Access Object 황제낙엽 2017.01.12 1920
230 SimpleDateFormat Symbol file 황제낙엽 2016.12.20 461
229 JSON-lib Java Library file 황제낙엽 2013.04.09 460
228 JSP 파일에서 getOutputStream() has already been called for this response 에러 황제낙엽 2013.04.24 11907
227 servlet 에서의 json 한글처리 황제낙엽 2013.04.23 1854
226 -file.encoding의 역할 (다국어, 한국어) 황제낙엽 2013.04.10 549
225 [The type HttpUtils is deprecated] javax.servlet.http.HttpUtils 황제낙엽 2013.03.20 569
224 com.oreilly.servlet.multipart 를 이용한 파일 업로드 file 황제낙엽 2013.03.19 443