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

번호 제목 글쓴이 날짜 조회 수
351 java.lang.IllegalArgumentException 황제낙엽 2010.01.18 130514
350 Using RSS in JSP pages (Informa Project) 황제낙엽 2006.01.10 37829
349 JSP 파일에서 getOutputStream() has already been called for this response 에러 황제낙엽 2013.04.24 11479
348 한글 파일명 깨짐으로 살펴본 다국어 처리 문제 (UTF-8) 황제낙엽 2012.03.22 10121
347 세션의 timeout 설정 >> HttpSession.setMaxInactiveInterval() 황제낙엽 2019.07.03 8311
346 [JSON기초04] 자바 JSON 데이터에서 KEY 값 알아오기 (TIP) 황제낙엽 2017.01.18 6641
345 java.util.Queue file 황제낙엽 2022.04.06 5382
» 쓰레드(Thread)를 중간에 종료시키는 방법 황제낙엽 2017.03.15 5127
343 Java 실행 옵션들 황제낙엽 2017.08.23 3367
342 일본어 전각 반각 변환 예제 소스 .첫번째 file 황제낙엽 2007.01.10 3070
341 byte배열에 대한 CRC 를 계산하는 메서드 (java.util.zip.CRC32) 황제낙엽 2010.03.14 2166
340 UTF형태 파일에서 BOM 제거하기 황제낙엽 2008.06.16 1938
339 File.delete() 와 File.deleteOnExit() 황제낙엽 2019.03.24 1887
338 [대용량 파일 업로드] multipart form parser - http file upload, database 저장 java class 연재2 file 황제낙엽 2009.06.19 1831
337 싱글톤 방식의 테스트용 Temporary Data Access Object 황제낙엽 2017.01.12 1603
336 servlet 에서의 json 한글처리 황제낙엽 2013.04.23 1519
335 날짜, 시간 문자열 값으로 Date 오브젝트로 만들기 >> SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.US) 황제낙엽 2017.10.31 1516
334 J2EE object-caching frameworks (ObjectCache) 황제낙엽 2007.11.02 1495
333 [대용량 파일 업로드] multipart form parser - http file upload 기능 java class 연재1 file 황제낙엽 2009.06.19 1436
332 JavaMail - 네이버 메일 수신하기(POP3) 황제낙엽 2018.08.20 1413