코드와 함께 싱글스레드와 멀티스레드에 대해서 포스팅해보겠습니다.
1. 스레드란?
하나의 프로세스 내부에서 독립적으로 실행되는 하나의 작업 단위라고 할 수 있다.
싱글 스레드
말 그대로 싱글이라고 생각하면 된다.
하나의 프로세스에서 하나의 스레드를 실행하는 것을 말한다.
하나의 레지스터와 스택으로 표현한다.
예시
public class Main {
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 3000; i++) {
System.out.print("-");
}
System.out.println();
System.out.println("첫번째 작업 걸린 시간 : [" + (System.currentTimeMillis()- start) + "] ms ");
for (int i = 0; i < 3000; i++) {
System.out.print("l");
}
System.out.println();
System.out.println("두번째 작업 걸린 시간 : [" + (System.currentTimeMillis()- start) + "] ms ");
}
}
멀티 스레드
그러면 멀티는 당연히 여러 개의 스레드를 사용하는 것을 말한다.
하나의 프로세스에서 다수의 스레드를 실행하는 것을 말한다고 볼 수 있다.
예시
public class Main {
public static void main(String[] args) {
long start = System.currentTimeMillis();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 3000; i++) {
System.out.print("-");
}
System.out.println();
System.out.println("첫번째 작업 걸린 시간 : [" + (System.currentTimeMillis()- start) + "] ms ");
}
}).start();
for (int i = 0; i < 3000; i++) {
System.out.print("l");
}
System.out.println();
System.out.println("두번째 작업 걸린 시간 : [" + (System.currentTimeMillis()- start) + "] ms ");
}
}
결과정리
싱글스레드 시간보다 멀티스레드의 소요 시간이 더 오래 걸린 것을 확인할 수 있고, 멀티스레드는 거의 동시에 작업이 완료되었습니다.
2. 왜 멀티스레드가 더 느릴까요?
멀티스레드로 작업하는 것이 느린 이유는 두 가지 이유가 있습니다.
1. 두 개의 스레드가 번갈아가면서 작업을 처리하기 때문에 Context Switching이 발생하기 때문입니다.
Context Switching
멀티 프로세스 또는 스레드 환경에서 CPU가 어떤 하나의 프로세스 또는 스레드를 실행하고 있는 상태에서, 인터럽트 요청에 의해 다음 우선순위의 프로세스가 실행되어야 할 때, 기존의 프로세스의 상태 또는 레지스터 값(Context)을 저장하고 CPU가 다음 프로세스를 수행하도록 새로운 프로세스의 상태 또는 레지스터 값(Context)으로 교체하는 작업을 콘텍스트 스위칭이라고 한다.
2. 한 스레드가 화면(console)에 출력하는 동안 다른 스레드는 출력이 끝나기를 기다려야 하는데, 이때 발생하는 대기시간 때문입니다.
즉, 공통된 화면이라는 자원에 대한 Race Condition이 발생하기 때문입니다.
Race Condition
두 개 이상의 병행한 프로세스(or 스레드)들이 하나의 자원에 접근하기 위해 경쟁하는 상태를 말합니다.
3. 그러면 빠른 싱글 스레드가 좋냐?
그건 또 아닙니다.
싱글 스레드와 멀티 스레드의 장단점에 따라, 상황에 따라서 맞는 스레드를 사용하면 될 것 같습니다.
예를 들어서 두 스레드가 서로 다른 자원을 사용하는 작업의 경우에는 싱글스레드보다 멀티스레드가 더 효율적이라고 볼 수 있습니다.
예시
1. 사용자로부터 입력을 받는 작업과 화면에 1초부터 10초까지 1초마다 'ㅣ'를 출력하는 작업을 하나의 스레드로 진행
public class Main {
public static void main(String[] args) {
long start = System.currentTimeMillis();
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
System.out.println(s);
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("ㅣ");
}
System.out.println("작업 완료되는데 걸리는 시간: [" + (System.currentTimeMillis()- start) + "] ms ");
}
}
결과
4초 즈음에 입력을 줬을 때 결과
2. 사용자로부터 입력을 받는 작업과 화면에 1초부터 10초까지 1초마다 'ㅣ'를 출력하는 작업을 멀티스레드로 진행
public class Main {
public static void main(String[] args) {
long start = System.currentTimeMillis();
new Thread(new Runnable() {
@Override
public void run() {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
System.out.println(s);
}
}).start();
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("ㅣ");
}
System.out.println("작업 완료되는데 걸리는 시간: [" + (System.currentTimeMillis()- start) + "] ms ");
}
}
결과
4초 즈음에 입력을 줬을 때 결과
어떤 작업을 하느냐에 따라 사용하기 나름인 것 같습니다.
끝!
'개발지식' 카테고리의 다른 글
메모리 구조, 힙(Heap) 영역과 스택(Stack) 영역의 차이 (4) | 2024.11.11 |
---|---|
[JSON] JSON은 도대체 뭐지? (0) | 2024.01.17 |
[통신] HTTP란? (0) | 2024.01.16 |
[Gradle] Gradle이란? (0) | 2024.01.12 |
[API] REST, REST API, RESTful 정리 (1) | 2024.01.11 |