elevne's Study Note
Java - Multi Thread (3) 본문
이번 시간에는 Daemon Thread 라는 것에 대해 알아보았다. Deamon 스레드는 주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드이다. 보조적인 역할의 데몬 스레드는 주 스레드가 종료되면 데몬 스레드는 강제 종료된다는 점 외에는 일반 스레드와 큰 차이가 없다고 한다. 데몬 스레드의 대표적인 예로는 워드의 자동 저장, 가비지 컬렉터 등이 있다. (해당 기능들 또한 마찬가지로 워드, JVM 등이 종료되면 같이 종료된다) Java 에서 스레드를 생성하고 데몬으로 만들기 위해서는 setDaemon(true); 메서드를 사용해주면 된다. 이 때, 스레드의 start() 메서드를 호출하고 나서 setDeamon() 을 사용하면 IllegalThreadStateException 이 발생하기 뒤기에 start() 전에 Deamon 으로 지정해줘야 한다.
package multithreading;
public class AutoSaveThread extends Thread {
public void save() {
System.out.println("SAVING...");
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
save();
}
}
}
public static void main(String[] args) {
AutoSaveThread autoSaveThread = new AutoSaveThread();
autoSaveThread.setDaemon(true);
autoSaveThread.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
System.out.println("MAIN THREAD DONE");
}
그 다음으로는 Thread Group 이라는 것에 대해 알아보았다. Thread Group 은 관련된 스레드를 묶어서 관리할 목적으로 이용된다. JVM 이 실행되면 system 스레드 그룹을 만들고, JVM 운영에 필요한 스레드를 생성해서 system 스레드 그룹에 포함시킨다. 그 다음 system 의 하위 스레드 그룹으로 main 을 만들고 main 스레드를 main 스레드 그룹에 포함시킨다.
스레드는 반드시 하나의 스레드 그룹에 속하게 된다고 한다. 명시적으로 스레드를 그룹에 따로 포함시키지 않으면 기본적으로 자신을 생성한 스레드와 같은 스레드 그룹에 속하게 된다.
public static void main(String[] args) {
AutoSaveThread autoSaveThread = new AutoSaveThread();
autoSaveThread.setDaemon(true);
autoSaveThread.setName("AutoSaveThread");
autoSaveThread.start();
Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
Set<Thread> threads = map.keySet();
for (Thread t : threads) {
System.out.println("NAME: "+t.getName()+((t.isDaemon()) ? "(데몬)" : "(주)"));
System.out.println("\t소속그룹: "+t.getThreadGroup().getName());
System.out.println();
}
}
위 예제에서는 getAllStackTraces() 메서드를 통해 프로세스 내에서 실행하는 모든 스레드 정보를 확인해본 것이다. 결과를 보면 가비지 컬렉션을 담당하는 Finalizer 스레드를 비롯한 여러 스레드가 system 그룹에 속하고, main 메서드를 실행하는 main 스레드는 main 그룹에 속하는 것을 확인할 수 있다.
이러한 스레드 그룹은 아래와 같이 생성해볼 수 있다.
public static void main(String[] args) {
ThreadGroup tg = new ThreadGroup("TEST GROUP");
Thread t = new Thread(tg, new Runnable() {
@Override
public void run() {
System.out.println("HI");
}
});
}
Thread 를 생성할 때, 해당 스레드가 속할 Thread Group 을 지정해줄 수 있는 것이다.
스레드를 스레드 그룹에 포함시키면 interrupt() 메서드를 이용하여 그룹 내에 포함된 모든 스레드들을 일괄 interrupt 해줄 수 있다. 각 스레드별로 interrupt() 를 따로 호출해줄 필요가 없어지는 것이다. (예외처리는 따로따로 해줘야한다.) 이 외에도 activeCount(), destroy(), getMaxPriority() 등 Thread Group 에서 사용할 수 있는 각종 메서드들이 있다.
package multithreading;
public class WorkThread extends Thread{
public WorkThread(ThreadGroup threadGroup, String threadName){
super(threadGroup, threadName);
}
@Override
public void run() {
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println(getName() + "is interrupted");
break;
}
}
System.out.println(getName() + "is done");
}
}
public static void main(String[] args) {
ThreadGroup myGroup = new ThreadGroup("myGroup");
WorkThread threadA = new WorkThread(myGroup, "threadA");
WorkThread threadB = new WorkThread(myGroup, "threadB");
threadA.start();
threadB.start();
System.out.println("[MAIN THREAD GROUP list() method]");
System.out.println();
ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
mainGroup.list();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {}
System.out.println("[MyGroup Thread Group interrupt()]");
System.out.println();
myGroup.interrupt();
}
list() 메서드는 현재 스데르 그룹과 이름의 최대 우선순위를 헤더로 출력하고, 그 아래에 현재 스레드 그룹에 포함된 스레드와 하위 스레드 그룹의 내요을 보여준다.
Reference:
이것이 자바다
'Backend > Java' 카테고리의 다른 글
Java - Collection (0) | 2023.05.17 |
---|---|
Java - Multi Thread (4) (0) | 2023.05.14 |
Java - Map Compute, To JSON (0) | 2023.05.10 |
Java - Multi Thread (2) (0) | 2023.05.09 |
Java - Multi Thread (1) (0) | 2023.05.07 |