q를 입력하면 예외가 발생하는데 그 이유를 모르겠습니다.
313
3 câu hỏi đã được viết
안녕하세요. 항상 강의 잘 듣고 있습니다 🙂
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() 부분에서 예외가 발생하고 로그도 안 찍혔을 것 같다는 생각이 들었습니다.
Câu trả lời 1
모니터와 synchronized, ReentrantLock, 원자적연산 CAS관련해서 추가적으로 더 깊게 공부했는데 제가 이해한 것이 맞나요??
0
81
1
Future cancel기능을 사용했지만 interrupt가 발생하지 않을 때 어떻게 처리해야하나요?
0
70
2
2.스레드 생성과 실행 - 17P 그림 문의
0
70
2
자바 동시성 현업에서 사용예시가 궁금합니다
0
128
1
ReentrantLock 동작 원리에 대한 질문입니다.
0
79
1
synchronized 대신 join 을 사용하여 순서를 보장할 경우 해법이 아닌가요?
0
90
2
메모리 가시성 문제 질문
0
65
1
Future4-이유 질문
0
61
1
오타 제보
0
70
2
runnable 질문
0
91
2
자바가 아닌 다른 언어에서도
0
107
1
메모리 가시성 문제가 발생하는 이유
0
122
1
데몬스레드가 어떨 때 사용이 되는지 궁금합니다.
0
76
1
Future.cancel() 취소를 사용하는 예가 궁금합니다.
0
81
1
synchronized 와 인스턴스의 lock
0
88
2
synchronized 키워드만으로 메모리 가시성이 해결되는 이유가 궁급합니다.
0
60
1
[스레드 풀과 Executor 프레임워크1][문제와 풀이] `log("일부 작업이 실패했습니다.");` 실행되는 경우가 있을까요?
0
55
1
원자적 연산이 멀티스레드 상황에서 안전한 이유를 제대로 이해했는지 확인 부탁드립니다
0
64
2
자바 고급 1,2,3편 같이 진행해도 문제없나요
0
74
2
CPU 캐시 때문에도 잔액이 200원이 될 수 있나요?
0
101
2
synchronized 메서드와 join 관련 질문이 있습니다.
0
66
2
섹션 14. 115번 강의 내용 질문
0
79
2
교안에 있는 7페이지 데이터 영역
0
47
1
Executor 스레드 풀 관리 질문
0
103
2

