인프런 커뮤니티 질문&답변

이종수님의 프로필 이미지

작성한 질문수

김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성

프린터 예제3 - 인터럽트 코드 개선

q를 입력하면 예외가 발생하는데 그 이유를 모르겠습니다.

작성

·

155

·

수정됨

0

안녕하세요. 항상 강의 잘 듣고 있습니다 🙂

public static void main(String[] args) throws InterruptedException {

        Printer printer = new Printer();
        Thread printerThread = new Thread(printer, "printer");
        printerThread.start();

        Scanner sc = new Scanner(System.in);

        while (true) {
            log("프린터할 문서를 입력하세요. 종료 (q): ");
            String str = sc.nextLine();
            if (str.equals("q")) {
                printerThread.interrupt();
                break;
            }
            printer.addJob(str);
        }
    }

 

static class Printer implements Runnable {

        Queue<String> jobQueue = new ConcurrentLinkedQueue<>();

        @Override
        public void run() {
            log("outer 상태 : " + Thread.currentThread().isInterrupted());
            while(!Thread.interrupted()) {
                try {
                    if (jobQueue.isEmpty()) {
                        continue;
                    }

                    String job = jobQueue.poll();
                    log("출력 시작: " + job + ", 대기 문서: " + jobQueue);
                    log("inner 상태 : " + Thread.currentThread().isInterrupted());
                    Thread.sleep(3000);
                    log("출력 완료");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    log("인터럽트!");
                    System.out.println(e.getMessage());
                    break;
                }
            }
            log("프린터 종료");
        }

        public void addJob(String str) {
            jobQueue.offer(str);
        }
    }

저는 q를 입력하면 인터럽트 상태가 false로 바뀌게 되고, 프린터 종료 로그가 남을 거라고 생각했습니다.

실행하고 바로 q를 입력하면 제가 예상한 대로 동작하지만, 값을 입력 후 q를 입력하면

Thread.sleep(3000);

이 부분에서 InterruptedException 예외가 발생했습니다.

저는 이 부분에서 의문점이 들었습니다.

while(!Thread.interrupted()

1. 인터럽트 상태가 바뀌었을 텐데 왜 예외가 발생하지?

2. 상태가 안 바뀌었나?

라는 생각을 하고 로그를 확인해봤는데

07:21:21.366 [  printer] outer 상태 : false

07:21:21.366 [     main] 프린터할 문서를 입력하세요. 종료 (q): 

123

07:21:22.790 [     main] 프린터할 문서를 입력하세요. 종료 (q): 

07:21:22.796 [  printer] 출력 시작: 123, 대기 문서: []

07:21:22.796 [  printer] inner 상태 : false

q

java.lang.InterruptedException: sleep interrupted

	at java.base/java.lang.Thread.sleepNanos0(Native Method)

	at java.base/java.lang.Thread.sleepNanos(Thread.java:491)

	at java.base/java.lang.Thread.sleep(Thread.java:522)

	at thread.control.printer.MyPrinterV3$Printer.run(MyPrinterV3.java:46)

	at java.base/java.lang.Thread.run(Thread.java:1570)

07:21:22.980 [  printer] 인터럽트!

sleep interrupted

07:21:22.980 [  printer] 프린터 종료

q를 입력하면 바로 예외가 발생해서 상태가 바뀌었는지는 잘 모르겠습니다.

만약 상태가 안 변했다고 해도 결국 sleep 부분에서 예외가 발생할 텐데, 로그가 안 찍힌 이유도 모르겠습니다.

그래서 여러 번 실행해본 결과 값 입력하고 3초 후 q를 입력하면 예외가 발생하지 않는다는 걸 알게 되었습니다.

잠자고 있는 스레드를 깨워서 문제가 발생하는 것 같은데 제 지식으로는 여기까지인 것 같습니다.

질문 1. while(!Thread.interrupted()) 이 부분에서 인터럽트 상태가 false로 변경되었을 것 같은데 예외가 발생한 이유를 모르겠습니다.

 

제가 다시 생각해보니 프린터 스레드는 sleep() 때문에 3초 기다리고 있는 상태에서 깨우니 sleep() 부분에서 예외가 발생하고 로그도 안 찍혔을 것 같다는 생각이 들었습니다.

 

답변 1

0

catch 문 내에 있는 e.printStackTrace(); 때문에 발생한 예외가 출력 된거 같아요!