chapter12. 멀티 스레드. 


12.8 스레드 그룹

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

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

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

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

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


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

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

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


12.8.1 스레드 그룹 이름 얻기


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package sec08.exam01_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();
        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();
        }
    }
}
cs



12.8.2 스레드 그룹 생성

- 명시적으로 스레드 그룹을 만드는 방법

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


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

- 새로운 스레드 그룹을 생성한 후, 이 그룹에 스레드를 포함시키려면 

Thread 객체를 생성할 때 생성자 매개값으로 스레드 그룹을 지정하면 된다.


12.8.3 스레드 그룹의 일괄 interrupt()

// 예를 들어 10개의 스레드들을 모두 종료시키기 위해 각 스레드에서 interrupt() 메소드를 10번 호출할 수도 있지만,

// 이 스레드들이 같은 스레드 그룹에 소속되어 있는 경우, 스레드 그룹의 interrupt() 메소드를 한 번만 호출해주면 된다.

// 이것이 가능한 이유는 스레드 그룹의 interrupt() 메소드는 포함된 모든 스레드의 interrupt() 메소드를 내부적으로 호출해주기 때문이다


// 스레드 그룹의 interrupt() 메소드는 소속된 스레드의 interrupt() 메소드를 호출만 할 뿐 

개별 스레드에서 발생하는 InterruptedException에 대한 예외 처리를 하지 않는다.

// 따라서 안전한 종료를 위해서는 개별 스레드가 예외 처리를 해야 한다.


// interrupt() 메소드로 스레드들을 안전하게 종료하도록 유도하는 것이 좋다.




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



- ThreadGroup이 제공하는 메소드



InterruptedException이 발생할 때 스레드가 종료되도록 함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package sec08.exam01_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; // InterruptedException이 발생될 때, while문을 빠져나와 스레드를 종료시킴
            }
        }
        System.out.println(getName() + " 종료됨");
    }
}
cs


스레드 그룹을 이용한 일괄 종료 예제 // 실행 클래스
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package sec08.exam01_threadgroup;
 
public class ThreadGroupExample {
    public static void main(String[] args) {
        ThreadGroup myGroup = new ThreadGroup("myGroup");
        WorkThread workThreadA = new WorkThread(myGroup, "workThreadA"); // myGroup에 두 스레드를 포함시킴
        WorkThread workThreadB = new WorkThread(myGroup, "workThreadB");
        
        workThreadA.start();
        workThreadB.start();
        
        System.out.println("[ main 스레드 그룹의 list() 메소드 출력 내용 ]");
        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();  // 현재 main스레드가 포함된 그룹 -> main   
        mainGroup.list(); // 현재 그룹에 포함된 스레드와 하위 그룹에 대한 정보를 출력한다
        System.out.println();
        
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
        }
        
        System.out.println("[ myGroup 스레드 그룹의 interrupt() 메소드 호출 ]");
        myGroup.interrupt(); // 현재 그룹에 포함된 모든 스레드들을 interrupt한다.
    }
}
cs
 






Posted by 너래쟁이
: