TIL

  1. 데몬 스레드
  2. 스레드의 상태, 실행제어
    • sleep()
    • interrupt()

 


 

데몬 스레드

  • 일반 스레드의 작업을 돕는 보조 역할을 한다.
  • 일반 스레드가 모두 종료되면 자동으로 종료된다.
  • 가비지 컬렉터, 자동저장, 화면 자동갱신 등에 사용된다.
  • 무한루프, 조건문을 이용해서 실행 후, 대기하다가 특정조건이 만족되면 작업을 수행하고 다시 대기하도록 작성한다.

 

boolean isDaemon() // 스레드가 데몬 스레드인지 확인한다.
void setDaemon(boolean on) // 스레드를 데몬 스레드 또는 사용자 스레드로 변경한다.
  • setDaemon(boolean on)은 반드시 start()를 호출하기 전에 실행되어야 한다. 그렇지 않으면 IllegalThreadStateException이 발생한다.

 

 

public class Main implements Runnable {
    static boolean autoSave = false;
    public static void main(String[] args) { // 메인 스레드
        Thread t = new Thread(new Main()); // 생성자 Thread(Runnable r)
        t.setDaemon(true);
        t.start();

        for (int i=1; i<=10; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {}
            System.out.println(i);

            if (i == 5) autoSave = true;
        }

        System.out.println("프로그램을 종료합니다.");
    }

    @Override
    public void run() { // 데몬 스레드
        while (true) {
            try {
                Thread.sleep(3 * 1000);
            } catch (InterruptedException e) {}

            if (autoSave) autoSave();
        }
    }

    public void autoSave() {
        System.out.println("자동저장 합니다.");
    }
}
1
2
3
4
5
자동저장 합니다.
6
7
8
자동저장 합니다.
9
10
프로그램을 종료합니다.
  • main()가 종료되자 데몬 스레드도 종료되었다. 만약 setDaemon()true로 설정하지 않았다면 프로그램은 종료되지 않았을 것이다.

 

 

 

 

스레드의 상태

  • NEW : 스레드가 생성되고 아직 start()가 호출되지 않은 상태
  • RUNNABLE : 실행 또는 실행 가능한 상태
  • BLOCKED : 동기화 블럭에 의해서 일시정지 된 상태(LOCK이 풀릴 때까지 기다림)
  • WAITING : 스레드의 작업이 종료되지 않았지만 실행가능하지 않은 일시정지 상태
  • TIMED_WAITING : 일시정지 시간이 지정된 상태
  • TERMINATED : 스레드의 작업이 종료된 상태

 

 

 

 

스레드의 실행제어

  • sleep() : 지정된 시간동안 스레드를 일시정지 시킨다. 시간이 지나면 자동으로 실행대기 상태가 된다.
  • join() : 다른 스레드를 기다린다.
  • interrupt() : 잠들어 있거나(sleep()) 기다리는 걸(join()) 깨운다.
  • stop() : 스레드를 즉시 종료 시킨다.
  • suspend() : 스레드를 일시정지 시킨다.
  • resume() : suspend()에 의해 일시정지 상태에 있는 스레드를 실행대기 상태로 만든다.
  • yield() : 실행 중인 자신에게 실행시간을 다른 스레드에게 양보하고 자신은 실행대기 상태가 된다.

 

(* dead-lock(교착상태)를 발생시킬 수 있기 때문에 suspend(), resume(), stop()은 deprecated 됐다.)

 

 

 

sleep()

static void sleep(long millis);
try { 
	// 이렇게 작성하면 th1은 sleep하게 만드는 것이라고 오해할 수 있다. 
    // 에러는 안 난다. 
    이 코드 또한 자기자신을 sleep하게 만드는 것이니까. 
    th1.sleep(3000); 
    
    // 💯 이렇게 작성해야 오해의 여지가 없다. 
    Thread.sleep(3000); 
}
  • 현재 스레드를 지정된 시간동안 멈추게 한다.
    • static 메소드이기 때문에 항상 현재 스레드, 즉 자기자신에 대해서만 동작한다.
    • 특정 스레드를 지정해서 멈추게 하는 것은 불가능하다.
  • 예외처리를 해야 한다.
    • InterruptedException이 발생하면 sleep 상태에서 깨어난다.

 

 

 

 

interrupt()

void interrupt() // 스레드의 interrupted(상태변수) 상태를 false -> true
boolean isInterrupted() // 현재 스레드의 interrupted 반환
static boolean interrupted() // 현재 스레드의 interrupted 상태를 알려주고, false로 초기화
  • 대기상태(waiting)인 스레드를 실행대기 상태(runnable)로 만든다.
    • 대기상태: 작업이 중단된 상태 ex) sleep(), wait(), join()

 

 

 

📚 참고
자바의 정석