[기본 개념] 8 | (1.2) 스레드 우선순위, 스레드 그룹, 데몬 스레드
1 프로세스와 쓰레드
2 쓰레드의 구현과 실행
3 start( )와 run( )
4 싱글쓰레드와 멀티쓰레드
5> 쓰레드의 우선순위
6> 쓰레드 그룹(thread group)
7> 데몬 쓰레드(daemon thread)
8 쓰레드의 실행제어
9 쓰레드의 동기화
9.1 synchronized를 이용한 동기화
9.2 wait( )와 notify( )
9.3 Lock과 Condition을 이용한 동기화
9.4 volatile
9.5 fork & join 프레임웍
5. 쓰레드의 우선순위
쓰레드는 우선순위라는 속성(멤버변수)를 가지고 있다. 이 우선순위의 값에 따라 쓰레드가 얻는 실행시간이 달라진다. 작업의 중요도에 따라 우선순위를 서로 다르게 지정하여 특정 쓰레드에게 더 많은 작업시간을 부여할 수 있다.
쓰레드의 우선순위 지정하기
void setPriority(int newPriority) 쓰레드의 우선순위를 지정한 값으로 변경한다.
int getPriority( ) 쓰레드의 우선순위를 반환하다.
public static final int MAX_PRIORITY = 10 // 최대우선순위
public static final int MIN_PRIORITY = 1 // 최소우선순위
public static final int NORM_PRIORITY = 5 // 보통우선순위
쓰레드가 가질 수 있는 우선순위의 범위는 1~10이며 숫자가 높을수록 우선순위가 높다. 또한 쓰레드의 우선순위는 쓰레드를 생성한 쓰레드로부터 상속받으며, main메서드 내에서 생성하는 쓰레드의 우선순위는 자동적으로 5가 된다.
윈도우즈에서 싱글 코어로 두 개의 쓰레드로 두 개의 작업을 실행하는 경우를 가정해보자.
우선순위가 같은 경우, 각 쓰레드에게 거의 같은 양의 실행시간이 주어진다.
th1 |
| A | | | A | | | A | | | A | | ||||
th2 |
| B | | | B | | | B | | | B | | ||||
t1→ | t2→ |
두 쓰레드의 우선순위가 같은 경우
우선순위가 다른 경우, 우선순위가 높은 th1에게 상대적으로 th2보다 더 많은 양의 실행시간이 주어지며 작업 A가 작업 B보다 빨리 완료된다.
th1 |
| A | | | A | | | A | | ||||||||
th2 |
| B | | | B | | | B | | ||||||||
t1→ | t2→ |
th1의 우선순위 th2의 우선순위보다 높은 경우
그러나 멀티코어에서는 쓰레드의 우선순위에 따른 차이가 전혀 없다.
쓰레드에 우선순위를 부여하는 대신 작업에 우선순위를 두어 PriorityQueue에 저장해놓고,
우선순위가 높은 작업 먼저 처리하는 게 낫다.
6. 쓰레드 그룹(thread group)
서로 관련된 쓰레드를 그룹으로 다루기 위한 것으로, 쓰레드를 그룹으로 묶어서 관리할 수 있다.
보안상의 이유로 도입된 개념으로, 자신이 속한 쓰레드 그룹이나 하위 쓰레드 그룹은 변경할 수 있지만 다른 쓰레드 그룹의 쓰레드를 변경할 수 없다.
모든 쓰레드는 반드시 그룹에 포함되어 있어야 하므로, 기본적으로 자신을 생성한 쓰레드와 같은 쓰레드 그룹에 속하게 된다. 생성하는 모든 쓰레드 그룹은 main쓰레드 그룹의 하위 쓰레드 그룹이 되며, 그룹을 지정하지 않으면 자동으로 main쓰레드 그룹에 속한다.
7. 데몬 쓰레드(daemon thread)
데몬 쓰레드는 다른 일반 쓰레드의 작업을 돕는 보조적인 역할을 수행하는 쓰레드이다. 일반 쓰레드가 모두 종료된 후 강제적으로 자동종료된다.
데몬 쓰레드는 무한루프와 조건문을 이용해서 실행 후 대기하다가 특정 조건이 만족되면 작업을 수행하고 다시 대기하도록 작성한다.
일반 쓰레드의 작성방법과 실행방법이 같으며, 쓰레드를 생성한 다음 실행하기 전 setDaemon(true)를 호출하기만 하면 된다.
예제/ThreadEx10.java
public class ThreadEx10 implements Runnable {
static boolean autoSave = false;
public static void main(String[] args) {
Thread t = new Thread(new ThreadEx10());
t.setDaemon(true); // 이 부분이 없으면 종료되지 않는다.
t.start();
for (int i = 1; i <= 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
System.out.println(i);
if (i == 5)
autoSave = true;
}
System.out.println("프로그램을 종료합니다.");
}
public void run() {
while (true) {
try {
Thread.sleep(3 * 1000); // 3초마다
} catch (InterruptedException e) {}
//autoSave의 값이 true이면 autoSave()를 호출한다.
if (autoSave) {
autoSave();
}
}
}
public void autoSave() {
System.out.println("작업파일이 자동저장되었습니다.");
}
}
실행결과
1
2
3
4
5
작업파일이 자동저장되었습니다.
6
7
8
작업파일이 자동저장되었습니다.
9
10
프로그램을 종료합니다.
3초마다 변수 autoSave의 값을 확인해서 ture이면 autoSave( )를 호출하는 일을 무한히 반복한다. 이때, 데몬 쓰레드로 설정하지 않았다면 강제종료하지 않는 이상 영원히 종료되지 않는다.
setDaemon메서드는 반드시 start( )를 호출하기 전에 실행되어야 한다. 그렇지 않으면 IllegalThreadStateException이 발생한다.
출처 | Java의 정석 (남궁 성)
'💠프로그래밍 언어 > Java' 카테고리의 다른 글
[기본 개념] 8 | (1.4) 스레드 실행제어 (0) | 2022.01.22 |
---|---|
[기본 개념] 8 | (1.3) 스레드 실행제어 (0) | 2022.01.22 |
[기본 개념] 8 | (1.1) 프로세스, 스레드, Start( ), Run( ), 싱글/멀티 스레드 (0) | 2022.01.18 |
[기본 개념] 7 | (1.2) 와일드 카드, 지네릭 메서드, 지네릭 타입 제거 (0) | 2022.01.17 |
[기본 개념] 7 | (1.1) 지네릭스 클래스 (0) | 2022.01.17 |