작성
·
159
·
수정됨
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() 부분에서 예외가 발생하고 로그도 안 찍혔을 것 같다는 생각이 들었습니다.