[Java] Thread#5, 스레드 그룹 개념 및 예제

Thread Group

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

- JVM이 실행될때
- system 스레드 그룹을 만듬 
- JVM 운영에 필요한 스레드들을 생성
- system 스레드 그룹에 포함시킴

 

스레드 그룹 이름 얻기
ThreadGroup group = Thread.currentThread().getThreadGroup();
String groupName = group.getName();
스레드 그룹 예제
public static void main(String[] args) {
	ThreadGroup group = Thread.currentThread().getThreadGroup();
	//System.out.println(group.getName());
		
	AutoSaveThread autoSaveThread = new AutoSaveThread();
	autoSaveThread.setName("AutoSaveThread");
	autoSaveThread.setDaemon(true);
	autoSaveThread.start();
		
	Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
	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();
	}
}

getAllStackTraces() : 프로세스 내에서 실행하는 모든 스레드에 대한 정보를 얻음.

결과
Name : Signal Dispatcher(데몬) 
소속그룹 : system 
Name : AutoSaveThread(데몬) 
소속그룹 : main 
Name : main(주) 
소속그룹 : main 
Name : Attach Listener(데몬) 
소속그룹 : system 
Name : Finalizer(데몬) - 가비지 컬렉터 담당. 
소속그룹 : system 
Name : Reference Handler(데몬) 
소속그룹 : system

작업스레드는 대부분 메인스레드에서 생성한다. 스레드의 그룹을 직접 정해주지 않으면 디폴드로 현재 스레드의 그룹에 속하게 된다. 따라서 AutoSaveThread는 메인스레드에서 생성하였으므로 메인스레드의 그룹에 속하는 main그룹에 속하였다.

 

ThreadGroup 클래스가 가지고 있는 주요 메소드
메소드 설명
int activeCount() 현재 그룹 및 하위 그룹에서 활동중인 모든 스레드의 수를 리턴한다.
int  activeGroupCount()

현재 그룹에서 활동 중인 모든 하위 그룹의 수를 리턴한다

void checkAccess() 현재 스레드가 스레드 그룹을 변경할 권한이 있는지 체크한다. 만약 권한이 없으면 SecurityException을 발생시킨다
void destroy() 현재 그룹 및 하위 그룹을 모두 삭제한다. 단, 그룹 내에 포함된 모든 스레드들이 종료 상태가 되어야 한다.
boolean isDestroyed() 현재 그룹이 삭제되었는지 여부를 리턴한다
int getMaxPriority() 현재 그룹에 포함된 스레드가 가질 수 있는 최대 우선순위를 리턴한다
void setMaxPriority(int pri) 현재 그룹에 포함된 스레드가 가질 수 있는 최대 우선순위를 설정한다
String getName() 현재 스레드 그룹의 이름을 리턴한다.
ThreadGroup getParent() 현재 스레드 그룹의 부모그룹을 리턴한다.
boolean parentOf(ThreadGroup g) 현재 그룹이 매개값으로 지정한 스레드 그룹의 부모인지 여부를 리턴한다.
void setDaemon(boolean daemon) 현재 그룹을 데몬그룹으로 설정한다.
void list() 현재 그룹에 포함된 스레드와 하위 그룹에 대한 정보를 출력한다.
void interrupt() 현재 그룹에 포함된 모든 스레드들을 interrupt한다.

 

스레드 그룹의 일괄적으로 interrupt() 호출

스레드 그룹을 사용하는 이점

- 그룹내 포함된 모든 스레드들을 일괄 interrupt() 시켜서 안전하게 종료할 수 있다. 여러번 할걸 한번에 가능하다는 것.
- 하지만 스레드 그룹의 interrupt() 메소드는 소속된 스레드의 interrupt() 메소드를 실행만 할뿐 개별 스레드의 InterruptedException 예외처리는 하지 않는다.

- 개별 스레드에서 InterruptedException 처리를 해주어야 한다.

 

- 예제

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()+ " 종료됨");
	}
}

public class Main{
	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 스레드 그룹의 interrupted() 메소드 호출]");
		myGroup.interrupt();
	}
}

- WorkThread 클래스를 보면 catch문으로 interrupt 예외처리를 해준 모습이다. while문을 돌면서 예외를 발생시키면 탈출한다.

- list 메소드는 현재 그룹의 이름과 최대 우선순위를 헤더로 출력하고 그아래 스레드 그룹에 포함된 스레드와 하위 스레드 그룹의 내용을 보여준다.

- 맨 아래쪽의 myGroup.interrupt() 메소드는 스레드 그룹에 포함된 모든 스레드에 interrupt() 메소드를 호출한다.

- 실행결과를 보면 메인스레드가 종료한 뒤 두개의 WorkThread 객체 스레드가 종료하는 것을 볼 수 있다.

 

- 결과

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

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

댓글

Designed by JB FACTORY