자바

[스레드] 9. 스레드 그룹

devjones 2022. 5. 1. 12:25

스레드 그룹

- 관련된 스레드를 묶어서 관리할 목적으로 이용

- 스레드 그룹은 계층적으로 하위 스레드 그룹을 가질 수 있다.

 

- 자동 생성되는 스레드 그룹

* system 그룹: JVM 운영에 필요한 스레드들을 포함

* system/main 그룹: 메인 스레드를 포함

 

- 스레드는 반드시 하나의 스레드 그룹에 포함

* 기본적으로 자신을 생성한 스레드와 같은 스레드 그룹에 속하게 된다.

* 명시적으로 스레드 그룹에 포함시키지 않으면 기본적으로 system/main 그룹에 속한다.

 

스레드 그룹 이름 얻기

ThreadGroup group = Thread.currentThread.getThreadGroup();
Stirng gruopName = group.getName();

 

예제)

package ex08_threadgroup;

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();
        }
    }
}
package ex08_threadgroup;

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

public class ThreadInfoExample {
    public static void main(String[] args) {
        AutoSaveThread autoSaveThread = new AutoSaveThread();
        autoSaveThread.setName("AutoSaveThread");
        autoSaveThread.setDaemon(true);
        autoSaveThread.start();

        Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();     // 스택의 모든 스레드 get
        Set<Thread> threads = map.keySet();

        for (Thread thread : threads) {
            System.out.println("Name: " + thread.getName() + (thread.isDaemon() ? "(데몬)" : "(주)"));
            System.out.println("\t" + "소속그룹: " + thread.getThreadGroup().getName());
            System.out.println();
        }
    }
}

실행결과:

Name: Reference Handler(데몬)
	소속그룹: system

Name: Common-Cleaner(데몬)
	소속그룹: InnocuousThreadGroup

Name: AutoSaveThread(데몬)
	소속그룹: main

Name: Signal Dispatcher(데몬)
	소속그룹: system

Name: main(주)
	소속그룹: main

Name: Finalizer(데몬)
	소속그룹: system

Name: Monitor Ctrl-Break(데몬)
	소속그룹: main

 

스레드 그룹 생성

ThreadGroup tg = new ThreadGroup(String name);
ThreadGroup tg = new ThreadGroup(ThreadGroup parent, String name);

- 부모(parent) 그룹을 지정하지 않으면 현재 스레드가 속한 그룹의 하위 그룹으로 생성

- 스레드를 그룹에 명시적으로 포함시키는 방법

Thread t = Thread(ThreadGroup group, Runnable target);
Thread t = Thread(ThreadGroup group, Runnable target, String name);
Thread t = Thread(ThreadGroup group, Runnable target, String name, long stackSize);
Thread t = Thread(ThreadGroup group, String name)

 

스레드 그룹의 일괄 interrupt()

- 스레드 그룹의 interrupt() 를 호출하면 소속된 모든 스레드의 interrupt() 가 호출된다.

 

예제)

package ex08_threadgroup;

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() + " interrupted");
                break;
            }
        }
        System.out.println(getName() + " 종료됨.");
    }
}
package ex08_threadgroup;

public class ThreadGroupExample {
    public static void main(String[] args) {
        ThreadGroup myGroup = new ThreadGroup("myGroup");
        WorkThread workThreadA = new WorkThread(myGroup, "workThreadA");
        WorkThread workThreadB = new WorkThread(myGroup, "workThreadB");

        workThreadA.start();
        workThreadB.start();

        System.out.println("[ main 스레드 그룹의 list() 메소드 출력 내용 ]");
        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
        mainGroup.list();
    }
}
[ main 스레드 그룹의 list() 메소드 출력 내용 ]
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[Monitor Ctrl-Break,5,main]
    java.lang.ThreadGroup[name=myGroup,maxpri=10]
        Thread[workThreadA,5,myGroup]
        Thread[workThreadB,5,myGroup]

==============================================

package ex08_threadgroup;

public class ThreadGroupExample {
    public static void main(String[] args) {
        ThreadGroup myGroup = new ThreadGroup("myGroup");
        WorkThread workThreadA = new WorkThread(myGroup, "workThreadA");
        WorkThread workThreadB = new WorkThread(myGroup, "workThreadB");

        workThreadA.start();
        workThreadB.start();

        System.out.println("[ main 스레드 그룹의 list() 메소드 출력 내용 ]");
        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
        mainGroup.list();
        System.out.println();

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
        }

        System.out.println("[ myGroup 스레드 그룹의 interrupt() 메소드 호출 ]");
        myGroup.interrupt();
    }
}

 

결과:

[ main 스레드 그룹의 list() 메소드 출력 내용 ]
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[Monitor Ctrl-Break,5,main]
    java.lang.ThreadGroup[name=myGroup,maxpri=10]
        Thread[workThreadA,5,myGroup]
        Thread[workThreadB,5,myGroup]

[ myGroup 스레드 그룹의 interrupt() 메소드 호출 ]
workThreadA interrupted
workThreadB interrupted
workThreadA 종료됨.
workThreadB 종료됨.