인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

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

생각하는자님의 프로필 이미지

작성한 질문수

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

인터럽트 - 시작2

인터럽트-시작2, 인터럽트 상태 질문이요

해결된 질문

작성

·

171

·

수정됨

1

 학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문 전에 다음을 꼭 확인해주세요.


1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
안녕하세요. 영한님 코드에서 인터럽트 상태가 true이었다가 false로 바뀌는것을 확인하였습니다.

근데, 여기서 문제가 발생합니다.

저가 똑같이 코드를 만들어 밨고 그랬지만

화면 처럼

image.png

인터럽트 상태 2개 전부다 false가 나오는 경우가 발생합니다.(7번-8번 돌리면 한번 꼴로 나오는 것 같더라고요.)

그래서 저의 코드가 문제가 있는가 보여서 pdf에 있는 코드를 붙여놓기, 하여도 동일한 결과가 가끔씩 나옵니다.

(빨리 돌리기 위해서 sleep 시간은 조정함.)

저의 컴퓨터가 문제가 있는 건가? 이런 생각도 하게 되는데,모르겠네요. 그래서 여쭈어 봅니다.

혹 저만 이런 결과가 나오는 건지?, 아니면 다른 분들 컴퓨터에서도 이런 결과가 나오는 건지 알고 싶네요.

추가1

여러번 코드 치고 돌린거 아닙니다. 맨처음 코드 실행했는데, 둘다false가 나와서, 당황해서 여러번 돌리게 되었습니다.

답변 부탁 드립니다.

답변 1

6

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 생각하는자님

결론부터 말씀드리자면 false, false가 나올 수 있습니다.

thread.interrupt()를 통해 다른 스레드에 인터럽트를 발생시키면, 인터럽트를 받은 스레드는 우선 인터럽트 상태가 됩니다.(true 상태)

그런데 이후에 sleep() 같은 메서드를 만나서 InterruptedException이 발생하게 되면, 그러니까 예외가 터지게 되면 이 순간 인터럽트의 상태가 초기화 됩니다. (false 상태)

 

보통은 main 스레드에서 인터럽트 상태를 만들고 바로 출력하기 때문에 true를 보지만

        log("작업 중단 지시 thread.interrupt()");
        thread.interrupt();
        log("work 스레드 인터럽트 상태1 = " + thread.isInterrupted());

 

인터럽트를 받은 work 스레드가 sleep() 코드 안에서 예외를 터트리는게 먼저 발생하는 경우, 인터럽트가 초기화 되기 때문에 출력1도 false가 되어 버립니다.

 

정리하며 다음과 같습니다.

 

왜 isInterrupted()가 true였다가 다시 false가 될까?

  1. interrupt()가 호출되면

    • JVM은 해당 쓰레드의 인터럽트 플래그true로 설정합니다.

  2. 쓰레드가 sleep(), wait(), join() 등을 하고 있다면

    • 해당 메서드들이 InterruptedException을 던지게 됩니다.

    • 그와 동시에 쓰레드의 인터럽트 플래그는 false로 자동 초기화됩니다.

  3. 메서드가 InterruptedException을 던지지 않았다면

    • thread.isInterrupted()의 값이 true로 유지됩니다.

즉, 쓰레드가 sleep()(또는 다른 블록 메서드)에 의해 블록된 시점interrupt()가 들어오면, 예외가 던져지면서 인터럽트 플래그가 바로 false로 초기화됩니다.
그렇지 않고 아직 sleep()에 걸려있지 않은 시점에 interrupt()가 들어왔거나, 혹은 예외가 던져지기 전에 isInterrupted()를 호출하면 true가 보일 수도 있습니다. 

 

이 부분은 지금은 이해하기 어려울 수 있는데요, 강의 뒷부분에서 자세히 설명드리니 참고해주세요 🙂

감사합니다.

생각하는자님의 프로필 이미지

와.. 이래서 쓰레드 가 어렵다는 거네요.. 친절히 설명해 주셔서 감사합니다.