본문 바로가기
멀티캠퍼스 풀스택 과정/Java의 정석

자바의 정석10-3 쓰레드의 우선순위와 쓰레드 그룹

by 이쟝 2022. 1. 13.

쓰레드의 우선순위(priority of thread)

- 작업의 중요도에 따라 쓰레드의 우선순위를 다르게 하여 특정 쓰레드가 더 많은 작업시간을 갖게 할 수 있다.

- 쓰레드는 우선순위라는 속성(멤버변수)를 갖고 있는 데 이 우선순위의 값에 따라 쓰레드가 얻는 실행시간이 달라진다. 

 

쓰레드의 우선순위 지정하기(메서드와 상수)

 

 

-> 쓰레드가 가질 수 있는 우선순위의 범위는 1~10이며 숫자가 높을수록 우선순위가 높다.

-> 쓰레드의 우선순위는 쓰레드를 생성한 쓰레드로부터 상속받음(main메서드를 수행하는 쓰레드는 5이므로 main메서드 내에서 생성하는 쓰레드의 우선순위는 자동적으로 5가 됨)

 

예제1) 

 

public class Ex13_6 {
	public static void main(String[] args) {
		ThreadEx6_1 th1 = new ThreadEx6_1(); // Thread를 상속받은 ThreadEx6_1객체 생성
		ThreadEx6_2 th2 = new ThreadEx6_2(); // Thread를 상속받은 ThreadEx6_2객체 생성
		
//		th1.setPriority(5);  // 초기화값은 5이다. 
		th2.setPriority(7);  // priority 값은 7로 줌
		 
		System.out.println("Priority of th1(-) : " + th1.getPriority()); // Priority of th1(-) : 5
		System.out.println("Priority of th2(|) : " + th2.getPriority()); // Priority of th2(|) : 7
		
		th1.start();  
		th2.start();
	}
}
class ThreadEx6_1 extends Thread {
	public void run() {
		for(int i=0;i<100;i++) {
			System.out.print("-");
			for(int x=0;x<10000;x++); // 시간지연용 for문
		}
	}
}
class ThreadEx6_2 extends Thread {
	public void run() {
		for(int i=0;i<100;i++) {
			System.out.print("|");
			for(int x=0;x<10000;x++);
		}
	}
}

 

더보기

<출력값> 

Priority of th1(-) : 5
Priority of th2(|) : 7
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||----------------------------------------------------------------------------------------------------

-> 확률적으로 -보다 | 빨리 끝나게 된다!(안그럴 경우도 있지만)

-> 쓰레드를 실행하기 전에만 우선순위를 변경할 수 있다. 

-> 우선순위가 높아지면 한 번에 작업이 끝나버릴 수 있어서 아무일도 하지 않은 반복문을 추가해 작업을 지연시킴(우선순위가 많이 차이나지 않아서 for문을 생략해도 큰 차이는 없음)

 


쓰레드 그룹(Thread Group)

- 서로 관련된 쓰레드를 그룹으로 묶어서 다루기 위한 것(쓰레드 그룹을 생성해서 쓰레드를 그룹으로 묶어서 관리 가능)

- 모든 쓰레드는 반드시 하나의 쓰레드 그룹에 포함되어 있어야 한다.

 

- 자신이 속한 쓰레드 그룹이나 하위 쓰레드 그룹은 변경할 수 있지만 다른 쓰레드 그룹의 쓰레드를 변경할 수 없음.

- 자신을 생성한 쓰레드(부모 쓰레드)의 그룹과 우선순위를 상속받는다.

- 쓰레드 그룹을 지정하지 않고 생성한 쓰레드main쓰레드 그룹에 속한다. (기본적으로 항상 만들던 쓰레드는 main쓰레드에서 만들기 때문에 main쓰레드 그룹에 속한다.)

 

- 쓰레드를 쓰레드그룹에 포함시키려면 Thread의 생성자를 이용해야 한다. (ThreadGroup을 사용해서 생성할 수 있다.)

 

 

*ThreadGroup의 생성자와 메서드*

 

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)
쓰레드  그룹에 속한 쓰레드 또는 하위 쓰레드 그룹의 목록을 지정된 배열에 담고 그 개수를 반환. 
두 번째 매개변수인 recurese의 값을 true로 하면 쓰레드 그룹에 속한 하위 쓰레드 그룹에 쓰레드 또는 쓰레드 그룹까지 배열에 담는다.
int getMaxPriority( ) 쓰레드 그룹의 최대우선순위를 반환
String getName( ) 쓰레드 그룹의 이름을 반환
ThreadGroup getParent( ) 쓰레드 그룹의 상위 쓰레드 그룹을 반환
void interrupt( ) 쓰레드 그룹에 속한 모든 쓰레드를 interrupt
boolean isDaemon( ) 쓰레드 그룹이 데몬 쓰레드 그룹인지 확인
boolean isDestroyed( ) 쓰레드 그룹이 삭제되었는지 확인
void list( ) 쓰레드 그룹에 속한 쓰레드와 하위 쓰레드 그룹에 대한 정보를 출력
boolean parentOf(ThreadGroup g)  지정된 쓰레드 그룹의 상위 쓰레드 그룹인지 확인
void setDaemon(boolean daemon) 쓰레드 그룹을 데몬 쓰레드 그룹으로 설정/해제
void setMaxPriority(int pri) 쓰레드 그룹의 최대 우선순위를 지정
ThreadGroup  getThreadGroup( ) 쓰레드 자신이 속한 쓰레드 그룹을 반환
void  uncaughtException(Thread t, Throwable e)  쓰레드 그룹의 쓰레드가 처리되지 않은 예외에 의해 실행이 종료되었을 때, JVM에 의해 이 메서드가 자동적으로 호출된다. 

 

예제) 쓰레드 그룹과 쓰레드를 생성하고 main.list()를 호출해서 main쓰레드 그룹의 정보를 출력하는 예제

 

public class ThreadEx9 {

	public static void main(String[] args) {
		ThreadGroup main = Thread.currentThread().getThreadGroup();
		ThreadGroup grp1 = new ThreadGroup("Group1");
		ThreadGroup grp2 = new ThreadGroup("Group2");
		
		//ThreadGroup (ThreadGroup parent, String name) 
		ThreadGroup subGrp1 = new ThreadGroup(grp1,"subGrp1");
		
		grp1.setMaxPriority(3); // 쓰레드 그룹 grp1의 최대우선순위를 3으로 변경
		
		Runnable r = new Runnable () {
			public void run() {
				try {
					Thread.sleep(1000);  // 쓰레드를 1초간 멈추게 한다. 
				} catch (InterruptedException e) {}
			}
		};
		
		// Thread(ThreadGroup tg, Runnable r, String name)
		new Thread(grp1,    r,   "th1").start();
		new Thread(subGrp1, r,   "th2").start();
		new Thread(grp2,    r,   "th3").start();
		
		System.out.println(">>List of ThreadGroup : " +main.getName() + 
				", Active ThreadGroup: " + main.activeGroupCount() +
				", Active Thread: " + main.activeCount());
		
		main.list();
	}
}

 

더보기

<출력값>

>>List of ThreadGroup : main, Active ThreadGroup: 3, Active Thread: 4
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    java.lang.ThreadGroup[name=Group1,maxpri=3]
        Thread[th1,3,Group1]
        java.lang.ThreadGroup[name=subGrp1,maxpri=3]
            Thread[th2,3,subGrp1]
    java.lang.ThreadGroup[name=Group2,maxpri=10]
        Thread[th3,5,Group2]

 

-> 새로 생성한 모든 쓰레드 그룹은 main 쓰레드 그룹의 하위 쓰레드 그룹으로 포함되어 있음

-> setMaxPriority()는 쓰레드가 쓰레드 그룹에 추가되기 전에 호출되어야 함

-> new Thread(grp1, r, "th1").start( ); => Thread th1 = new Thread(grp1, r, "th1";  th1.start();