백_곰 2022. 2. 14. 17:33

1. 데몬 쓰레드에 대한 기본 개념

- 데몬 쓰레드다른 일반 쓰레드의 작업을 돕는 보조적인 역할을 수행하는 쓰레드이다.

 

- 일반 쓰레드가 종료되면 데몬 쓰레드도 강제적으로 종료되는데, 그 이유는 일반 쓰레드를

보조 역할로 수행하는데 없으면 있을 이유가 없기 때문이다.

 

- 데몬 쓰레드의 예로는 가비지 컬렉터, 워드프로세서의 자동저장, 화면자동갱신 등이 있다.

 

- 데몬 쓰레드는 무한 루프와 조건문을 이용해서 실행 후 대기하고 있다가 특정조건이 만족되면

작업을 수행 후 다시 대기한다.

 

- 데몬 쓰레드는 일반 쓰레드의 작성방법과 실행방법이 같으나, 쓰레드를 생성한 다음 실행하기 전에

setDaemon(true)를 호출해주어야 한다.

 

- 데몬 쓰레드가 생성한 쓰레드는 자동적으로 데몬 쓰레드가 된다.

 

 

 

 

2. 데몬 쓰레드를 이해하기 위한 예제(1)

: 데몬 쓰레드가 어떻게 돌아가는지 알아보는 예제이다.

 

import java.util.*;

public class Exercise007 implements Runnable{
	static boolean autoSave = false;
	
	public static void main(String[] args) {
		Thread t = new Thread(new Exercise007());
		t.setDaemon(true);
		t.start();
		
		for(int i=0; i<=10; i++) {
			try {
				Thread.sleep(1000);
			}catch (Exception e) {
				// TODO: handle exception
			}
			System.out.println(i);
			
			if(i==5) autoSave = true;
		}
		System.out.println("프로그램을 종료합니다.");
	}
	//쓰레드가 무한반복중인데, 데몬쓰레드로 설정했기 때문에 종료가 된다.
	@Override
	public void run() {
		while(true) {
			try {
				Thread.sleep(3*1000);
				System.out.println("----------------");
			}catch (Exception e) {
				// TODO: handle exception
			}
			
			if(autoSave) {
				autoSave();
			}
		}
	}
	public void autoSave() {
		System.out.println("작업 파일이 저장되었습니다.");
	}
}

 

( 여기서 보면 데몬 쓰레드는 while(true)로 무한 루프를 가지고 있는데, 만약 이것이 일반

쓰레드라고 가정하면 영원히 안 멈출 것이다. )

( 그러나 데몬 쓰레드로 setDaemon(true)을 해주었기 때문에 main이 종료되니 같이 끝나게

되었다. )

( 또한 setDaemon(true)을 start()전에 출력하지 않으면 IllegalThreadStateException이 발생한다. )

 

 

 

 

3. 데몬 쓰레드를 이해하기 위한 예제(2)

: getAllStackTraces()를 이용하면 실행 중 또는 대기상태와 같이 작업이 완료되지 않은 모든 쓰레드의

호출스택을 출력할 수 있다.

 


import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Exercise008 {

	public static void main(String[] args) {
		Thread t1 = new ThreadEx5("Thread1");
		Thread t2 = new ThreadEx6("Thread2");
		t1.start();
		t2.start();
	}
}

class ThreadEx5 extends Thread{
	public ThreadEx5(String name) {
		super(name);
	}
	public void run() {
		try {
			Thread.sleep(5*1000);
		}catch (Exception e) {
			// TODO: handle exception
		}
	}
}

class ThreadEx6 extends Thread{
	public ThreadEx6(String name) {
		super(name);
	}
	public void run() {
		Map map = getAllStackTraces();
		Iterator it = map.keySet().iterator();
		
		int x=0;
		while(it.hasNext()) {
			Object obj = it.next();	
			Thread t = (Thread) obj;
			StackTraceElement[] ste = (StackTraceElement[]) (map.get(obj));
			
			System.out.println("["+ ++x + "] name: " + t.getName()
					+ ", group: " + t.getThreadGroup().getName()
					+ ", daemon: " + t.isDaemon());
			
			for(int i=0; i<ste.length; i++) {
				System.out.println(ste[i]);
			}
			System.out.println();
		}
	}
}

 

( 총 9개의 쓰레드를 가지며, 대부분 system, main 쓰레드의 그룹을 가진다. )