[F-Lab 모각코 챌린지 24일차] main 스레드, 싱글스레드와 멀티스레드, I/O blocking, 우선순위, 스레드 그룹
TIL
- thread
- main 스레드
- 싱글스레드와 멀티스레드
- I/O blocking
- 스레드 우선순위
- 스레드 그룹
1. main 스레드
main()
메소드의 코드를 수행하는 스레드- 스레드는 사용자 스레드와 데몬 스레드 두 종류가 있다.
- main 스레드는 사용자 스레드이다.
- 데몬 스레드는 <사용자 스레드의 보조 역할>을 하는 스레드이다.
- 실행 중인 사용자 스레드가 하나도 없을 때, 프로그램은 종료된다.
- main 스레드가 종료돼도 실행 중인 스레드가 있으면 프로그램은 종료되지 않는다.
public class Main {
public static void main(String[] args) {
Thread1 th1 = new Thread1();
Thread2 th2 = new Thread2();
th1.start();
th2.start();
System.out.println("==== main method 종료 ====");
}
}
class Thread1 extends Thread {
public void run() { // 스레드가 수행할 작업
for (int i = 0; i < 300; i++) {
System.out.print(0);
}
}
}
class Thread2 extends Thread {
public void run() { // 스레드가 수행할 작업
for (int i = 0; i < 300; i++) {
System.out.print(1);
}
}
}
- main 스레드가 먼저 종료되고 th1 스레드, th2 스레드 그리고 마지막으로 프로그램이 종료된다.
public class Main {
public static void main(String[] args) {
Thread1 th1 = new Thread1();
Thread2 th2 = new Thread2();
th1.start();
th2.start();
try {
// main 스레드가 th1, th2 스레드의 작업이 끝날 때까지 기다린다.
th1.join();
th2.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("==== main method 종료 ====");
}
}
- main 스레드가 마지막에 종료되고, 최종적으로 프로그램이 종료된다.
2. 싱글스레드와 멀티스레드
싱글스레드
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 300; i++) {
System.out.println("-");
}
for (int i = 0; i < 300; i++) {
System.out.println("|");
}
}
}
- 첫번째 반복문이 다 끝나야 두번째 반복문이 실행되므로 두 작업이 절대 겹치지 않는다.
멀티스레드
- 위에서 봤던 코드와 그 출력값처럼 두 작업이 번갈아 가며 실행된다.
- 싱글스레드로 작업한 시간보다 멀티스레드로 작업한 시간이 조금 더 걸린다.
- A작업에서 B작업으로 넘어가는 것을 context swithcing이라고 한다.
- 실행할 작업에 대한 정보 등이 바뀌기 때문에 context switching을 할 때, 시간이 소요가 된다.
- 멀티스레드 방식으로 작업을 하면 시간이 더 걸리는데 왜 멀티스레드 방식을 사용할까?
- 시간이 더 걸리더라도 동시에 2가지 작업을 할 수 있다.
- 작업을 효율적으로 관리 할 수 있다. (I/O blocking)
3. 스레드의 I/O blocking
- I/O blocking : 입출력 시, 작업중단
- 싱글스레드 방식에서 blocking이 발생하면 다음 작업을 진행할 수 없다.
- 디스크에 저장돼있는 파일을 읽어올 때, 시간이 걸리는데 싱글스레드로 프로그램을 작성하면 파일을 읽어오는 그 시간동안 아무 것도 못한다.
- 멀티스레드 방식에서 blocking이 발생하면 그냥 다른 작업을 진행할 수 있다.
public class Main {
public static void main(String[] args) { // 싱글스레드
// 작업A
String input = JOptionPane.showInputDialog("input 입력:");
System.out.println("입력된 input 값은 " + input);
// 작업B
for (int i = 10; i > 0; i--) {
System.out.print(i);
}
}
}
4. 스레드 우선순위
- 작업의 중요도에 따라 스레드의 우선순위를 다르게 하여 특정 스레드가 더 많은 작업시간을 갖게 할 수 있다.
- 자바에서는 스레드가 1~10까지 우선순위를 보유할 수 있다.
- 1: 최소 우선순위
- 5: 보통 우선순위
- 10: 최대 우선순위
- 스레드의 우선순위를 지정해주지 않으면 보통 우선순위(5)로 지정된다.
- 만약 우선순위를 변경하고 싶다면
setPriority()
메소드를 이용해서 변경할 수 있다. - 이 우선순위는 JVM에서 정해놓은 것이고 실제 Windows OS에서는 우선순위가 내부적으로 32단계로 정의되어있다.
- 이 우선순위는 단지 희망사항에 불과하고 OS의 스케줄러에게 전달한다.
- OS는 단지 이 우선순위를 참고만할 뿐이다. OS가 돌리는 많은 프로세스와 스레드 중에 특별히 JVM 내의 스레드만 더 우대해서 더 빨리 작업하게 해줄 순 없다.
- 그렇기 때문에 이 우선순위에 크게 기대를 하면 안 된다. 그냥 확률적으로 더 높은 우선순위를 가진 스레드가 빨리 작업 되겠거니...(아닐 때도 있음)
5. 스레드 그룹
- 서로 관련된 스레드를 그룹으로 묶어서 다루기 위한 것
- 모든 스레드는 반드시 하나의 스레드 그룹에 포함되어 있어야 한다.
- 스레드 그룹을 지정하지 않으면 생성한 스레드는 자동으로 <main 스레드 그룹>에 속한다.
- 자신을 생성한 스레드(부모 스레드)의 그룹과 우선순위를 상속받는다.
- main 스레드가 main 스레드 그룹에 속하기 때문에 우리가 생성하는 스레드는 다 main 스레드 그룹에 속한다.
// Thread 클래스 생성자 파라미터에 ThreadGroup 포함
public Thread(ThreadGroup group, Runnable target, String name,
long stackSize) {
}
📚 참고
자바의 정석
'JAVA' 카테고리의 다른 글
[F-Lab 모각코 챌린지 26일차] 스레드의 동기화 (0) | 2023.07.03 |
---|---|
[F-Lab 모각코 챌린지 25일차] 데몬 스레드 / 스레드의 상태, 실행제어 (0) | 2023.07.02 |
[F-Lab 모각코 챌린지 23일차] Binary Search Tree 제거 구현 (0) | 2023.06.30 |
[F-Lab 모각코 챌린지 22일차] Binary Search Tree, thread (0) | 2023.06.29 |
[F-Lab 모각코 챌린지 21일차] Binary Tree 순회 방법과 구현 (0) | 2023.06.28 |
댓글
이 글 공유하기
다른 글
-
[F-Lab 모각코 챌린지 26일차] 스레드의 동기화
[F-Lab 모각코 챌린지 26일차] 스레드의 동기화
2023.07.03 -
[F-Lab 모각코 챌린지 25일차] 데몬 스레드 / 스레드의 상태, 실행제어
[F-Lab 모각코 챌린지 25일차] 데몬 스레드 / 스레드의 상태, 실행제어
2023.07.02 -
[F-Lab 모각코 챌린지 23일차] Binary Search Tree 제거 구현
[F-Lab 모각코 챌린지 23일차] Binary Search Tree 제거 구현
2023.06.30 -
[F-Lab 모각코 챌린지 22일차] Binary Search Tree, thread
[F-Lab 모각코 챌린지 22일차] Binary Search Tree, thread
2023.06.29