본문 바로가기
Work & Study/JAVA (& 혼공자Java)

자바(Java) - 스레드 제어2

by a.k.a DUKI 2021. 1. 7.
728x90
반응형

스레드 상태제어 1을 이어서,

dustink.tistory.com/95

 

자바(Java) - 스레드 제어1

스레드를 생성하고 시작하면 스레드는 다양한 상태를 갖게 된다. 스레드의 상태는 자동으로 변경될 수도 있고, 코드에 의해 변경될 수있다. 스레드 객체를 생성하고 start()메소드를 호출 하면 바

dustink.tistory.com

 

 

스레드 상태 제어

스레드의 안전한 종료

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()메소드를 이용한다.

  • 데몬 스레드: 주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드 이다. 주 스레드가 종료되면 데몬 스레드는 강제적으로 종료 된다.

 

본 내용은 #혼자공부하는자바 책을 참고해 공부하려 작성했습니다.
728x90
반응형