경진의 블로그

스레드 - 스레드의 종료 본문

개인참고자료/자바(네트워크)

스레드 - 스레드의 종료

aith 2008. 7. 11. 02:13
스레드의 종료

run() 메소드의 실행을 완료한다. (run() 메소드의 실행이 종료되면 스레드가 종료된다.)
interrupt() 메소드로 실행을 일시중지 시킨다.

interrupt()를 실행해서 일시정시를 만들면 while문에서 판단후 바로 빠져나갈 수 있다.
while(!Thread.currentThread().isInterrupted()

스레드를 시작시킨 이후 그 스레를 중간에 중지하려면 예전에는 stop()이라는 메소드가 있었다. 여러 문제점으로 인해 썬社에서는 이 메소드를 사용하지 말 것을 권고한다. 따라서 현재는 크게 두 가지 방식으로 구현할 수 있다.

플래그를 이용하는 방법이다.
클래스의 stop() 메소드를 호출하면 stopped 값이 true로 변경되고 다음번 while문에서 루프를 빠져나가게 되어 run()메소드를 종료하고 스레드가 소멸된다.

//StopThread.java
public class StopThread implements Runnable {
    // 조건문 빠져나가기 위해 사용할 플래그 변수이다.
    private boolean stopped = false;
    public void run() {
        // stopped 플래그를 while 문 조건으로 사용한다.
        while (!stopped) {
            System.out.println("Thread is alive..");
            try {
                // 0.5초간 멈춘다.
                // 이곳에서 sleep 메소드를 호출하는 이유는
                // while 같은 반복문을 잠시의 여유없이 수행하면 CPU에 많은 부담을 주기 때문이다.
                // sleep 메소드 부분을 빼고 다시 컴파일 한 후에 CPU 사용률을 측정해보면,
                // 확연히 차이가 날 것이다.

                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Thread is dead..");
    }
    // 이 메소드 호출로 StopThread 를 멈춘다 
    public void stop() {
        stopped = true;
    }
}

public class StopThreadTest {
    public static void main(String[] args) {
        System.out.println("# Start StopThreadTest.java");
        StopThreadTest stt = new StopThreadTest();
        stt.process();
    }
    public void process() {
        // StopThread 인스턴스를 생성한 후 이 인자를 파라미터로 받는
        // 스레드 인스턴스를 생성한 후에 출발한다.
 
        StopThread st = new StopThread();
        Thread thread = new Thread(st);
        thread.start();
        try {
            // 1초간 멈춘다.
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        // StopThread 를 정지한다.
        st.stop();
    }
}

이 방법에는 몇가지 문제점이 있는데, 만약 스레드가 run() 메소드 안에 특정 로직에서 무한 루프를 돌거나 조건 루프를 도는 시간이 너무 오래 걸리는 작업을 한다면 stopped 플래그를 검사할 수 없다. 이렇게 되면 stop() 메소드로 스레드를 정지시켜도 스레드가 정지되지 않거나 한참 후에나 정지되는 문제점이 생기게 된다. 따라서 run() 메소드 안의 처리 로직 시간이 길다면 stopped 플래그를 자주 검사할 수 있도록 중간중간에 체크문을 적절히 삽입해야 한다.

interrupt() 메소드를 사용한다.
interrupt() 메소드는 현재 수행하고 있는 명령을 바로 중지한다.
interrupt() 메소드를 호출하는 시점에서 Object 클래스의 wait() 메소드나  Thread 클래스의 join(), sleep() 메소드가 호출된 경우에는 예외(InterruptException)이 발생된다.

//AdvancedStopThread.java
public class AdvancedStopThread implements Runnable {
    public void run() {
        try {
              // isInterrupted() 메소드를 while 문 조건으로 사용. 만약 이 스레드에 interrupt() 메소드를 호출한다
              // isInterrupted() 메소드는 true 를 리턴해서 while 문을 빠져나가게 된다.
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("Thread is alive..");
                // 0.5초간 멈춤.
                Thread.sleep(500);
            }
        } catch (InterruptedException e) {
            // 예상했던 예외이므로 무시..
        } finally {
            // 마무리 해야할 작업이 있다면 이곳에서 정리한다 꼭 실행하는 부분이다. 
            System.out.println("Thread is dead..");
        }
    }
}

//AdvancedStopThreadTest.java
public class AdvancedStopThreadTest {
        public static void main(String[] args) {
                System.out.println("# Start AdvancedStopThreadTest.java");
                AdvancedStopThreadTest astt = new AdvancedStopThreadTest();
        astt.process();
    }
    public void process() {
        // AdvancedStopThread 인스턴스를 생성한 후 이 인자를 파라미터로 받는
        // 스레드 인스턴스를 생성한 후에 출발시킨다.

        AdvancedStopThread ast = new AdvancedStopThread();
        Thread thread = new Thread(ast);
        thread.start();
        try {
            // 1초간 멈춘다.
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        // AdvancedStopThread 를 정지시킨다.
        thread.interrupt();
    }
}

while 조건문에 플래그 대신 isInterrupted() 메소드로 스레드가 일시 정지되었는지 확인한다. 또한 interrupt() 메소드를 호출한 즉시 스레드를 중지시키고 finally문서에서 안전하게 마무리 작업(소켓이나 스트림, DB 커넥션등 종료 작업)까지 할 수 있다.
0 Comments
댓글쓰기 폼