[혼자 공부하는 자바] 7/30 12-2 [스레드 제어] [스레드 일시정지] [sleep()] [안전한 종료] [interrupt()] [InterruptedException] [주스레드] [데몬스레드]

2020. 7. 31. 01:41·JAVA

 


//스레드 상태, 일시정지, 안전한 종료, 데몬스레드//

스레드의 상태를 변경해서 스레드를 제어하는 방법을 공부하는 챕터

 

 

cf) start()메소드를 사용했다고 해서 바로 실행되는 건 아니다. 사실은 실행 대기 상태가 된다.

실행 대기 상태에서 run()메소드 내용이 모두 실행되면 스레드의 실행이 멈추고 종료

내용 : 혼공자 541페이지

 

<<공부할 내용>>

ㅇ스레드 상태

ㅇ스레드 상태 제어

ㄴ주어진 시간 동안 일시정지

ㄴ스레드의 안전한 종료

ㅇ데몬스레드


스레드 상태

ㅇ실행(running)상태 :

ㄴ스레드 객체 생성 -> start() 메소드 호출 => 실행 대기 상태 (실행을 기다리고 있는 상태)

ㄴ운영체제는 실행 대기 상태의 스레드 중 하나의 스레드를 선택하고, CPU(코어)가 run()메소드를 실행하도록 한다. 이 때를 실행상태라고 한다.

ㄴ실행상태의 스레드는 run()메소드를 모두 실행하기 전에 다시 실행대기 상태로 돌아갈 수 있다. 그리고 실행 대기 상태에 있는 다른 스레드가 선택되어 실행 상태가 되고.. 이런식으루 실행상태와 실행대기상태를 번갈아가면서 각 스레드의 run()메소드를 조금씩 실행해나간다.

 

ㅇ종료(terminated)상태 : 

ㄴ실행상태에서 run()메소드가 종료되면 더이상 실행할 코드가 없다. 스레드의 실행이 멈추게 된다.

=>종료 상태

 

ㅇ일시정지 상태 : 

ㄴ경우에 따라서 실행상태에서 일시정지 상태로 가기도 한다. =>스레드가 실행할 수 없는 상태!!

ㄴ바로 실행 상태로 돌아갈 수 없다. 일시정지 상태에서 빠져나와 '실행 대기 상태로 가야 한다'

 


스레드 상태 제어

ㅇ실행 중인 스레드의 상태를 변경하는 것

ㅇ정교한 스레드 상태 제어가 필요 :

잘못된 상태제어는 먹통을 만든다. 스레드의 상태변화를 만드는 메소드를 잘 파악해야 한다.

 

1) 주어진 시간 동안 일시정지

2) 스레드의 안전한 종료 

 


1) 주어진 시간 동안 일시정지

★Thread클래스의 정적 메소드 sleep() 사용하기 (1/1000초 단위)

(저번 예제에서 다뤘었다!! try-catch문 속에 넣었었는데!!)

ㄴ일시정지 시간 다 가기 전에 interrupt() 메소드를 호출한다면

InterruptedException이 발생한다. => 그래서 예외 처리가 필요했던 것

ㄴsleep()메소드에서 일시정지 시간이 끝나면 자동적으로 실행 대기 상태가 된다.

 

★Interrupt() 메소드 : 일시 정지 상태의 스레드에서 InterruptedException을 발생시키기 때문에

예외처리 코드(catch)를 써서 실행대기상태로 가거나 종료상태로 갈 수 있도록 한다.

 

 

try {

  Thread.sleep(1000);

} catch(InterruptedException e) {

  //interrupt() 메소드가 호출되면 실행

}

 

 

<<3초 주기로 10번 비프음을 발생하게 하는 예제>>

 

소리 나게 하니까 쫌 신기해

sleep()메소드 실행으로 메인스레드를 3초동안 일시정지 상태로 보내고,

3초 후 다시 실행준비상태로 돌아온다.


2) 스레드의 안전한 종료

ㅡ해당 스레드의 run() 메소드가 모두 실행되면 자동으로 스레드가 종료된다.

ㅡ하지만 실행중인 스레드를 종료시켜야 한다면?? (예: 동영상을 중간에 끈다)

 

+불안전한 stop() 메소드는 deprecated다 : 이걸로 갑자기 종료하게 되면 스레드가 사용중이던 자원(파일, 네트워크 연결)들이 불안전한 상태로 남겨지기 때문에, 이제 사용되지 않는다고 한다.

 

"안전하게"스레드를 종료하려면? ㅡ stop 플래그 이용하기

=>run()메소드의 정상적인 종료를 유도한다.

★stop플래그 필드를 boolean으로 선언해서 while문을 작성하는 방식!

<<예제ㅣ setStop() >>

실행하고 1초 후 setStop(true)

(출력작업스레드 start()로 실행대기상태->실행 1초 할 수 있도록 메인스레드를 setStop(true)코드 실행 전에 1초동안 sleep(1000)로 일시정지키켰다.)

 

1초 출력(실행) 후 setStop(true)로 출력작업스레드를 정지한 모습

 

++ interrupt() 메소드를 이용하는 방법

헉 예외 발생하면 안되는게 아니었구나

스레드가 일시정지 상태일 때 interrupt()메소드는 InterruptedException을 발생시키는 역할을 하는데

이걸 이용하면 run()메소드를 정상 종료할 수 있다고 한다!! 아 예외를 이용해서 정상종료를해??

아 이런 방식으로

내용 : 혼공자 546페이지

ㅇThreadA에서 ThreadB의 interrupt()메소드를 실행 -> ThreadB가 sleep()메소드로 '일시정지 상태가 될 때' ThreadB에서 InterruptedException이 발생 -> 예외처리(catch)블록으로 이동 즉 while문을 빠져나올 수 있게 되고, 정리할거 정리한 뒤 run()메소드를 종료할 수 있게 된다.

 

 

<<예제 - InterruptedException을 일으켜서 스레드를 종료시키기>>

시작후 일단 메인스레드는 1초동안 일시정지 상태에 들어가고, 1초가 지나면 작업thread에 interrupt()를 작동시킨다.

이렇게 interrupt()메소드가 걸린 상태에서.. 작업thread가 일시정지 상태가 되면 (Thread.sleep(1);) 예외가 발생하여 catch블록으로 가서 while문을 빠져나올 수 있게 된다.

+스레드가 저어어 나중에라도 일시정지 상태가 되지 않으면 interrupt()메소드 호출은 아무의미가 없다.

 

 

+interrupt()메소드가 호출된 상태인지 확인하는 방법+

->호출되었다면 다음 두 메소드가 true를 리턴한다.

boolean status = Thread.interrupted();

boolean status = objThread.isInterrupted();

둘 중 아무거나 써도 무방하다 한다.

 

-interrupted() => 정적 메소드 => 현재 스레드가 interrupted되었는지 확인한다.

-isInterrupted() => 인스턴스 메소드 => 현재 스레드가 interrupted되었는지 확인한다.

 

 

<<작업스레드의 interrupt()가 호출되었는지 확인하기>>

이번엔 sleep(1)메소드를 사용하지 않고 interrupted()메소드로 확인해보자.

 

이렇게 if문을 이용해 interrupted() true가 맞으면 break를 통해서 while문을 빠져나올 수 있다.. 


데몬스레드

>주 스레드 돕는 "보조적인 스레드" => 주스레드가 종료되면 데몬스레드는 자동 강제종료!!

>이 점 빼면 일반 스레드와 데몬 스레드는 큰 차이 없다.

 

데몬스레드 적용 예: 워드프로세서의 자동저장, 미디어플레이어의 동영상 및 음악 재생, 쓰레기 수집기

>>주 스레드(워드, 플레이어, JVM)이 종료되면 같이 종료되는 데몬 스레드

 

 

★스레드를 데몬으로 만드는 방법

=> 주 스레드가 setDaemon(true)를 호출하면 된다.

Thread1 thread = new Thread1();

thread.setDaemon(true);

thread.start();

.

.

 

!! thread.start();전에 setDaemon(true) 해야 한다. 안 그러면 IllegalThreadStateException 발생한다.

!! 현재 실행 중인 스레드가 데몬스레드인지 확인하려면 isDaemon() 메소드의 리턴값을 보자.

 

 

<<주스레드, 데몬 스레드 예제>>

 

데몬스레드가 1초간격으로 save()하다가, 메인스레드가 종료되면 데몬스레드도 종료되는 것을 볼 수 있다.

반응형

'JAVA' 카테고리의 다른 글

[혼자 공부하는 자바] 7/31 13-1 [List 컬렉션] [ArrayList] [Vector] [LinkedList]  (0) 2020.07.31
[혼자 공부하는 자바] 7/31 13-1 [컬렉션 프레임워크]  (0) 2020.07.31
[혼자 공부하는 자바] 7/29 12-1 [스레드] [멀티 스레드] [프로세스] [작업 스레드] [메인 스레드] [공유객체] [동기화메소드]  (0) 2020.07.29
[혼자 공부하는 자바] 7/28 11-2 [java.util 패키지]  (0) 2020.07.29
HashMap이 뭘까\('o')/??  (0) 2020.07.26
'JAVA' 카테고리의 다른 글
  • [혼자 공부하는 자바] 7/31 13-1 [List 컬렉션] [ArrayList] [Vector] [LinkedList]
  • [혼자 공부하는 자바] 7/31 13-1 [컬렉션 프레임워크]
  • [혼자 공부하는 자바] 7/29 12-1 [스레드] [멀티 스레드] [프로세스] [작업 스레드] [메인 스레드] [공유객체] [동기화메소드]
  • [혼자 공부하는 자바] 7/28 11-2 [java.util 패키지]
히어로맛쿠키
히어로맛쿠키
  • 히어로맛쿠키
    yeny_lab
    히어로맛쿠키
  • 전체
    오늘
    어제
    • 분류 전체보기 (389)
      • 미분류글 (32)
        • ㅇ (2)
      • JAVA (84)
        • Effective Java (1)
        • Application (21)
      • 컴퓨터구조 & OS (28)
      • 자료구조 + 알고리즘 (43)
      • Database (12)
      • 컴파일러 (10)
      • 수학 (33)
        • 미분방정식 (12)
      • 데이터분석과 머신러닝 (38)
      • 기타 (59)
      • yyeeennyy (25)
  • 공지사항

    • ^o^/♡
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
히어로맛쿠키
[혼자 공부하는 자바] 7/30 12-2 [스레드 제어] [스레드 일시정지] [sleep()] [안전한 종료] [interrupt()] [InterruptedException] [주스레드] [데몬스레드]
상단으로

티스토리툴바