스레드 상태 제어

이전엔 스레드 상태에 대해 알아봤는데, 해당 스레드 상태를 제어하는 메소드에 대해 알아보자.

스레드 상태 다이어그램

https://velog.velcdn.com/images%2Fjakeseo_me%2Fpost%2Fdca75e88-003f-4136-9a6a-cca24449a3f0%2Fimage.png

스레드 상태제어 메소드

interrupt()

일시 정지 상태의 스레드에서 InterruptedException 예외를 발생시켜 예외처리 코드에서 실행 대기 상태로 가거나 종료 상태로 갈 수 있도록 한다.

sleep(long millis[, int nanos])

주어진 시간 동안 스레드를 일시 정지 상태로 만든다.(TIMED_WAITING) 주어진 시간이 지나면 자동적으로 실행 대기 상태가 된다.

일시 정지 상태에서 주어진 시간을 다 기다리기 전에 .interrupt() 메소드가 호출되면 InterruptedException이 발생한다.

join(), join(long millis[, int nanos])

join() 메소드를 호출한 스레드는 일시 정지 상태가 된다. 실행 대기 상태로 가려면 join() 메소드를 멤버로 가지는 스레드가 종료되거나, 매개값으로 주어진 시간이 지나야 한다.

ThreadA에서 ThreadB의 .join() 메소드를 호출하면, ThreadA는 ThreadB의 작업이 끝날 때까지 일시정지 상태가 된다.

비동기에서 타이밍이 안 맞아 버그가 생기거나 의도하지 않았던 동작이 생기는 경우는 매우 흔하다. 이 경우 .join() 메소드를 이용해 해결할 수 있다.

public class CalcThread extends Thread{
    private long sum = 0;

    public long getSum() {
        return sum;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            this.sum += i;
        }
    }
}
public class Main {
    public static void main(String[] args) {
        CalcThread calcThread = new CalcThread();
        calcThread.start();

        long sum = calcThread.getSum();
        System.out.println("sum = " + sum);
    }
}

https://velog.velcdn.com/images%2Fjakeseo_me%2Fpost%2F5e49f8d2-f126-4784-8c0d-3638b4ebe648%2Fimage.png

sum = 0이 나온다. CalcThread의 .run() 메소드가 끝나기 전에 print가 먼저 호출되어서 그렇다.

이럴 때 .join()을 써서 다른 스레드의 종료를 기다릴 수 있다.