자바 쓰레드 (3) - 쓰레드 그룹 (Thread Group)

자바

2020. 4. 19. 20:01

Thread Group (쓰레드 그룹)

start()함수를 잘 보면, start0()을 실행하기 전에, group에 add하고 있는 것을 볼 수 있다. 쓰레드를 쓰레드 그룹에 넣는 과정인데, 그렇다면 Thread Group은 뭘까?

생성자 및 메소드 설명
ThreadGroup(String name) 지정된 이름의 새로운 쓰레드 그룹을 생성
ThreadGroup(ThreadGroup parent, String name) 지정된 쓰레드 그룹에 포함되는 새로운 쓰레드 그룹 생성
int activeCount() 쓰레드 그룹에 포함된 활성상태에 있는 쓰레드의 수를 반환
int activeGroupCount() 쓰레드 그룹에 포함된 활성상태에 있는 쓰레드 그룹의 수를 반환
void checkAccess() 현재 실행중인 쓰레드가 쓰레드 그룹을 변경할 권한이 있는지 체크
void destroy() 쓰레드 그룹과 하위 쓰레드 그룹까지 모두 삭제한다.
int enumerate(Thread[] list) int enumerate(Thread[] list, boolean recurse) int enumerate(ThreadGroup[] list) int enumerate(ThreadGroup[] list, boolean recurse) 쓰레드 그룹에 속한 쓰레드 또는 하위 쓰레드 그룹의 목록을 지정된 배열에 담고 그 개수를 반환 두 번째 매개변수인 recurse의 값을 true로 하면 하위 쓰레드 그룹에 쓰레드 또는 쓰레드 그룹까지 배열에 담는다.
int getMaxPriority() 쓰레드 그룹의 최대우선순위를 반환
String getName() 쓰레드 그룹의 이름을 반환
ThreadGroup getParent() 쓰레드 그룹의 상위 쓰레드그룹을 반환
void interrupt() 쓰레드 그룹에 속한 모든 쓰레드를 interrupt
boolean isDaemon() 쓰레드 그룹이 데몬 쓰레드그룹인지 확인
boolean isDestroyed() 쓰레드 그룹이 삭제되었는지 확인
void list() 쓰레드 그룹에 속한 쓰레드와 하위 쓰레드그룹에 대한 정보를 출력
boolean parentOf(ThreadGroup g) 지정된 쓰레드 그룹의 상위 쓰레드그룹인지 확인
void setDeamon(boolean daemon) 쓰레드 그룹을 데몬 쓰레드그룹으로 설정, 해제
void setMaxPriority(int pri) 쓰레드 그룹의 최대우선순위를 설정

 

쓰레드를 특정 쓰레드 그룹에 포함시키려면 아래의 생성자를 이용하여야하고, 그렇지 않은 경우에는 자신을 생성한 쓰레드의 그룹과 동일한 그룹에 포함된다.

public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
} // 그룹 미지정

public Thread(ThreadGroup group, Runnable target) {
    init(group, target, "Thread-" + nextThreadNum(), 0);
} // 그룹 지정

private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {

        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
        if (g == null) { 
        // 그룹이 null이라면 (그룹 미지정)

			if (security != null) {
                g = security.getThreadGroup();
            }

            if (g == null) {
                g = parent.getThreadGroup();
                // 자신을 생성한 쓰레드의 그룹을 가져옴
            }
        }
        
        g.checkAccess();
        if (security != null) {
            if (isCCLOverridden(getClass())) {
                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
            }
        }

        g.addUnstarted();
        this.group = g;
        // 그룹을 지정한 경우, 해당 그룹이 this.group이 되고,
        // 그룹을 지정하지 않은 경우, 자신을 생성한 group이 this.group이 됨
        
        /* ... 생략 ... */
}

 

쓰레드 그룹을 이용하면 다수의 쓰레드를 한번에 조작할 수 있다. 최대 우선순위 설정, 인터럽트, 데몬쓰레드로 설정, 삭제 등의 작업이 가능하다. 그럼 직접 쓰레드 그룹을 사용해보자.

import java.util.concurrent.TimeUnit;

public class Main {

    public static void main(String[] args) {
        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
        // 메인 그룹
        
        ThreadGroup g1 = new ThreadGroup("g1");
        ThreadGroup g2 = new ThreadGroup("g2");
        // 두개의 쓰레드 그룹 생성
        
        ThreadGroup subGroup = new ThreadGroup(g1, "sub_g1");
        // 서브 그룹 생성

        g1.setMaxPriority(3);
        // 그룹1의 최대 우선순위를 3으로 설정
        
        Runnable r = () -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }; // 작업 정의

        new Thread(g1, r, "th1").start();
        new Thread(subGroup, r, "th2").start();
        new Thread(g2, r, "th3").start();
        // 각각 g1, sub_g1, g2에 포함된 쓰레드 작업 시작

        System.out.println("List of TheadGroup : " + mainGroup.getName()
                + ", Active ThreadGroup: " + mainGroup.activeGroupCount()
                + ", Active Thread: " + mainGroup.activeCount() + "\n");

        mainGroup.list();
        // 쓰레드 및 그룹 정보 출력
    }
}

출력 : 
List of TheadGroup : main, Active ThreadGroup: 3, Active Thread: 5

java.lang.ThreadGroup[name=main,maxpri=10] // 가장 root인 메인 그룹
    Thread[main,5,main] // 메인 쓰레드
    Thread[Monitor Ctrl-Break,5,main] // 모니터 쓰레드
    
    java.lang.ThreadGroup[name=g1,maxpri=3] // g1그룹 
        Thread[th1,3,g1] // g1 그룹의 쓰레드 th1
        java.lang.ThreadGroup[name=sub_g1,maxpri=3] // g1의 서브그룹
            Thread[th2,3,sub_g1] // 서브 그룹의 쓰레드 th2
    
    java.lang.ThreadGroup[name=g2,maxpri=10] // g2그룹
        Thread[th3,5,g2] // g2그룹의 쓰레드 th3

쓰레드 1과 2는 g1과 sub_g1에 있기 때문에 이들의 최대 우선순위가 3으로 설정 되었음을 알 수 있다.