https://m.blog.naver.com/qbxlvnf11/220837131449
- 멀티 태스킹(multi tasking)과 멀티 스레드(multi thread)
컴퓨터를 사용할 때 노래를 들으면서 워드 파일을 작성을 할 수 있는 것처럼 컴퓨터의 운영체제는 두 개의 작업을 동시에 진행할 수 있습니다. 이와 같이 두 가지 이상의 작업을 동시에 처리하는 것을 '멀티 태스킹(multi tasking)'이라고 하는데, 하나의 프로세스(실행 중인 하나의 어플리케이션) 내에서도 멀티 태스킹을 할 수도 있습니다.
이 프로세스들은 스레드가 여러 개 사용되는 멀티 스레드 방식을 사용함으로써 멀티 태스킹을 합니다. 하나의 스레드는 하나의 코드 실행 흐름이기 때문에 한 프로세스 내에 여러 개의 스레드를 사용한다면 동시 작업이 가능한 멀티 태스킹을 할 수 있습니다.
▶멀티 스레드의 실행방식: 동시성(Concurrency), 병렬성(Parallelism)
동시성: 멀티 작업을 위해 하나의 코어에서 멀티 스레드가 번갈아가며 실행하는 성질
병렬성: 멀티 작업을 위해 멀티 코어에서 개별 스레드를 동시에 실행하는 성질
싱글 코어 CPU를 이용한 멀티 스레드 작업은 번갈아 실행하는 것이 워낙 빠르다보니까 병렬적으로 실행되는 것처럼 보이지만, 사실은 번갈아가며 실행하는 동시성 작업입니다.
▶스레드 스케줄링(Thread scheduling): 스레드의 개수가 코어(CPU)의 수보다 많을 경우, 스레드를 어떤 순서에 의해 동시성으로 실행할 것인가를 정하는 작업
스레드 스케줄링에 의해 스레드들은 아주 짧은 시간에 번갈아가면서 그들의 run()메소드를 조금씩 실행합니다.
- 스케줄링 방식
우선순위(Priority) 방식: 우선순위가 높은 스레드가 실행 상태를 더 많이 가지도록 스케줄링하는 것으로, 스레드 객체에 우선 순위 번호를 부여할 수 있기 때문에 개발자가 코드로 제어할 수 있습니다.
순환 할당(Round-Robin) 방식: 시간 할당량(Time Slice)을 정해서 하나의 스레드를 정해진 시간만큼 실행하고 다시 다른 스레드를 실행하는 방식으로, 자바 가상 기계(JVM)에 의해서 정해지기 때문에 코드로 제어할 수 없습니다.
우선순위 방식에서 우선순위는 1에서부터 10까지 부여되는데, 1이 가장 우선순위가 낮고, 10이 가장 높습니다. 우선순위를 부여하지 않으면 모든 스레드들은 기본적으로 5의 우선순위를 할당받습니다.
우선순위를 변경하는 메소드: thread.setPriority(우선순위);
- 스레드 우선순위 예제
( 스레드를 구현 하는 방법은 여러 가지가 있는데 스레드 관련 포스팅들의 예시에서 다양한 방법을 사용해 스레드를 구현해 보며 익힐 예정입니다. )
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public class ReferenceType{
public static void main(String[]args){
Thread thread1 = new Thread(new Runnable(){ // main 스레드 우선순위 5
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0; i<2000000000; i++){}
System.out.println("1");
}
});
thread1.setName("내가 첫 번째로 실행됬어!"); // 스레드 이름 설정
System.out.println(thread1.getName()); // 스레드 이름 출력
Thread thread2=new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0; i<2000000000; i++){}
System.out.println("2");
}
});
thread2.setName("내가 두 번째로 실행됬어!");
System.out.println(thread2.getName());
Thread thread3=new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0; i<2000000000; i++){}
System.out.println("3");
}
});
thread3.setName("내가 세 번째로 실행됬어!");
System.out.println(thread3.getName());
Thread thread4=new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0; i<2000000000; i++){}
System.out.println("4");
}
});
thread4.setName("내가 네 번째로 실행됬어!");
System.out.println(thread4.getName());
Thread thread5=new Thread(new Runnable(){ // 우선순위를 지정안 함!=> 자동으로 우선순위 5설정
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0; i<2000000000; i++){}
System.out.println("5");
}
});
thread5.setName("내가 다섯 번째로 실행됬어!");
System.out.println(thread5.getName());
// 우선순위 설정
// 숫자가 높을수록 우선순위가 높음
thread1.setPriority(Thread.MIN_PRIORITY); // 우선순위: 1
thread2.setPriority(7);
thread3.setPriority(8);
thread4.setPriority(Thread.MAX_PRIORITY); // 우선순위: 10
// 스레드 실행
// 우선순위가 높다고 해서 항상 먼저 나오는 것은 아님=>우선순위가 높은 스레드는 단지 실행 상태를 더 많이 가지도록 스케줄링 당하는 것이기 때문임
// 실행할 때마다 결과가 약간씩 바뀌지만 우선순위가 높은 스레드가 먼저 실행되는 경우가 빈번함
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
}
}
<결과>
우선순위의 차이가 많이 나지 않는 4, 3, 2의 순서가 조금 다를 때도 있지만 대부분 우선순위가 높은 순서대로 출력이 됩니다.
4(우선순위: 10), 3(우선순위: 8), 2(우선순위: 7), 5(우선순위 5), 1(우선순위: 1)