스레드 상태제어 1을 이어서,
스레드 상태 제어
스레드의 안전한 종료
2. interrupt() 메소드를 이용하는 방법
interrupt()메소드는 스레드가 일시 정지 상태 일때 InterruptedException을 발생키는 역할을 한다.
ThreadA가 ThreadB의 interrupt()메소드를 실행하면,
ThreadB가 sleep()메소드가 일시 정지 상태가 될 때
ThreadB에서 InterruptedException이 발생하여 예외 처리(catch)블록으로 이동.
ThreadB는 while문을 빠져나와 run()메소드를 정상 종료 하게 된다.
아래 예제는 PrintThread2를 실행한 후 1초 후에 PrintThread2를 멈추도록 interrupt()메소드를 호출한다.
예시1) 1초 후 출력 스레드를 중지
public class InterruptEx {
public static void main(String[] args) {
Thread thread = new PrintThread2();
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
// 스레드를 종료하기 위해 InterruptedException을 발생시킴
thread.interrupt();
}
}
무한 반복해서 출력하는 스레드
public class PrintThread2 extends Thread {
public void run() {
try {
while (true) {
System.out.println("실행 중");
Thread.sleep(1); // InterruptedException 발생
}
} catch (InterruptedException e) {
}
System.out.println("자원 정리");
System.out.println("실행 종료");
}
}
스레드가 실행대기 또는 실행상태에 있을때 interrupt()메소드가 실행되면,
즉시 InterruptedException이 발생되지 않고, 추후 일시 정지 상태가 되면 InterruptedException이 발생한다.
일시정지 상태가 되지 않으면 interrupt()메소드는 소용이 없다. --> Thread.sleep(1); 그래서 사용
일시 정지 만들지 않고 interrupt() 호출 여부를 알 수 있는 방법.
interrupt()메소드가 호출되었다면 스레드의 interrupted()와 isInterrupted() 메소드는 true를 리턴한다.
- interrupted(): 정적 메소드로 현재 스레드가 interrupted 되었는지 확인
- isInterrupted(): 인스턴스 메소드로 현재 스레드가 interrupted 되었는지 확인
boolean status = Thread.interrupted();
boolean status = objThread.isInterrupted();
다음 코드는 Thread.sleep(1); 를 사용하지 않고 Thread.interrupted()를 사용하여 확인한다.
예시2) 무한 반복해서 출력하는 스레드
public class PrintThread2 extends Thread {
public void run() {
while(true) {
System.out.println("실행 중");
if(Thread.interrupted()) {
break;
}
}
System.out.println("자원 정리");
System.out.println("실행 종료");
}
}
데몬 스레드 (daemon Thread)
데몬 스레드: 주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드
주 스레드가 종료되면 데몬 스레드는 자동으로 종료가 된다. 데몬 스레드는 주 스레드의 보조역할을 하기 때문이다.
데몬 스레드를 만들기 위해서는 메인 스레드가 주 스레드가 되고, 데몬이 될 스레드를 setDaemon(true)를 호출해주면 된다.
public static void main(String[] args){
AutoSaveThread thread = new AutoSaveThread();
thread.setDaemon(true);
thread.start();
..
}
start() 메소드가 호출 되고 setDaemon(true)를 호출하면 IllegalThreadStateException이 발생한다.
setDaemon(true) 호출 후 -> start()메소드 호출해야한다.
현재 실행 중인 스레드가 데몬 스레드인지 아닌지 구별하려면 inDaemon()메소드의 리턴값을 조사하면된다. 데몬 스레드는 true를 리턴 한다.
데몬 스레드는 워드프로세서의 자동 저장, 미디어 플레이어의 동영상 및 음악 재생 등에서 사용되며, 주 스레드(워드프로세서, 미디어 플레이어 등)이 종료되면 같이 종료된다.
다음 예시는 1초 주기로 save()메소드를 자동 호출하도록 AutoSaveThread를 작성,
메인스레드가 3초 후 종료되면 AutoSaveThread도 같이 종료되도록 데몬스레드로 만든다.
예시3) 1초 주기로 save()메소드를 호출하는 데몬 스레드
public class AutoSaveThread extends Thread {
public void save() {
System.out.println("작업 내용 저장");
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
save();
}
}
}
메인 스레드가 실행하는 코드
public class DaemonEx {
public static void main(String[] args) {
AutoSaveThread autoSaveThread = new AutoSaveThread();
autoSaveThread.setDaemon(true); // AutoSaveThread를 데몬 스레드로 만듦
autoSaveThread.start();
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
System.out.println("메인 스레드 종료");
}
}
Thread.sleep(3000); 라고 코딩 하면 왜 결과가 책 처럼 안될까나, 4000으로 바꾸면 제대로 나오긴 하는데, 왜 먼저 종료 되는지 모르겠네 이거.
흠.. 이건 좀더 공부해바야 겠다. 왜 먼저 메인 스레드 종료 가 뜨는지,
※용어 정리
-
스레드 상태: 스레드를 생성하고 시작하면 스레드는 다양한 상태를 갖는다. 스레드는 자동으로 혹은 코드에 의해서 변경 될 수 있다.
-
일시 정지: 실행 중인 스레드를 일정 시간 동안 멈추게 하려면 sleep() 사용하면 된다. Thread.sleep() 메소드는 일정시간동안 멈추고 그 후 다시 실행 대기 상태로 돌아간다.
-
안전한 종료: Thread는 스레드를 즉시 종료하기 위해 stop()메소드를 제공하나, 사용 중이던 자원들이 불안전하게 종료되어 사용하지 않는다. 안전하게 종료하기 위해 stop 플래그 또는 interrupt()메소드를 이용한다.
-
데몬 스레드: 주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드 이다. 주 스레드가 종료되면 데몬 스레드는 강제적으로 종료 된다.
본 내용은 #혼자공부하는자바 책을 참고해 공부하려 작성했습니다.
'Work & Study > JAVA (& 혼공자Java)' 카테고리의 다른 글
자바(Java) - 컬렉션 프레임워크 (List 컬렉션 1) (1) | 2021.01.12 |
---|---|
자바(Java) - 스레드 제어1 (0) | 2021.01.07 |
자바(Java) - 스레드5 (동기화 메소드) (0) | 2020.12.30 |
자바(Java) - 스레드4 (스레드 이름) (0) | 2020.12.21 |
자바(Java) - 스레드3 (toolkit.beep(); 비프음 실행) (0) | 2020.12.21 |