inflearn logo
강의

Khóa học

Chia sẻ kiến thức

Lập trình Java thực tế của Kim Young-han - Nâng cao phần 1, đa luồng và đồng thời

Máy in Ví dụ 3 - Cải thiện mã ngắt

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

313

dkffkekahsl13615

3 câu hỏi đã được viết

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

 

java 객체지향 동시성 multithread thread

Câu trả lời 1

0

chobo

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

모니터와 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