병행(concurrent)와 병렬(parallel)
싱글 코어에서 하나의 쓰레드로 두 개의 작업을 수행한 시간보다 오히려 두 개의 쓰레드로 작업한 시간이 싱글쓰레드로 작업한 시간보다 더 걸리게 되는데 그 이유는 쓰레드간의 context swtiching에 시간이 걸리기 때문이다. 따라서 싱글 코어에서 단순히 CPU만을 사용하는 계산 작업이라면 오히려 멀티쓰레드보다 싱글쓰레드로 프로그래밍하는 것이 더 효율적이다.
다음은 하나의 쓰레드로 두 가지 작업을 하는 코드와 결과이다.
public class ThreadEx4 {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < 300; i++) {
System.out.printf("%s", new String("-"));
}
System.out.println("소요시간1:" + (System.currentTimeMillis() - startTime));
for (int i = 0; i < 300; i++) {
System.out.printf("%s", new String("|"));
}
System.out.println("소요시간2:" + (System.currentTimeMillis() - startTime));
}
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------소요시간1:7
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||소요시간2:12
다음은 두 개의 쓰레드로 작업을 하나씩 나누어서 수행한 코드와 그 결과이다.
public class ThreadEx5 {
static long startTime = 0;
public static void main(String[] args) {
ThreadEx5_1 th1 = new ThreadEx5_1();
th1.start();
startTime = System.currentTimeMillis();
for (int i = 0; i < 300; i++) {
System.out.printf("%s", new String("-"));
}
System.out.println("소요시간1:" + (System.currentTimeMillis() - ThreadEx5.startTime));
}
}
class ThreadEx5_1 extends Thread {
@Override
public void run() {
for (int i = 0; i < 300; i++) {
System.out.printf("%s", new String("|"));
}
System.out.println("소요시간2:" + (System.currentTimeMillis() - ThreadEx5.startTime));
}
}
-----||-------||||||||||||||||||||---------------------------------|||----------||||||||---||||||||||||||-----------------|||||||||||||||||||-------------------|||||||||||||||||||||||||||||||---|||||||||------------------------------|||||||--------------------|||||||||||||||-------|||||||||--||||||||||||||||||||||||||||||||||||||||-----|||||||||------------------------------||||||||||||||||||||||||||-----------------||||||||||||||----------------|||||||||||||||||||||||||-------------||------------------------------||||||---------------------------------|||||||||||||||||||||||||||||||||||||||||소요시간2:13
소요시간1:12
두 작업이 아주 짧은 시간동안 번갈아가면서 실행되면서 거의 동시에 작업이 완료되었다.
또한 같은 작업을 싱글 코어로 실행했을 때와 멀티 코어로 실행했을 때로도 비교해서 생각해볼 수 있다.
싱글 코어의 경우에는 멀티쓰레드라도 하나의 코어가 번갈아가변서 작업을 수행하는 것이므로 두 작업이 절대로 겹치지 않는다.
하지만 멀티코어에서는 멀티쓰레드로 동시에 두 쓰레드가 수행될 수 있으므로 두 작업이 겹칠 수 있다. 그래서 화면이라는 자원을 놓고 두 쓰레드가 경쟁하는 상황에 놓일 수 있다.
이때, 여러 쓰레드가 여러 작업을 동시에 진행하는 것을 병행(concurrent)라고하고, 하나의 작업을 여러 쓰레드가 나눠서 처리하는 것을 병렬(parallel)이라고 한다.
따라서 위의 상황은 병행의 예이다.
두 쓰레드가 서로 다른 자원을 사용하는 작업
위의 예제는 두 쓰레드가 하나의 자원(console)을 차지하고자 하는 작업이었다면, 두 쓰레드가 서로 다른 자원을 사용하는 작업의 경우에는 멀티쓰레드가 더 효율적이다. 예를들어, 사용자의 입력을 기다리는 동안 다른 쓰레드가 작업을 처리할 수 있기때문이다.
인용
자바의 정석
'Language > Java' 카테고리의 다른 글
ThreadLocal 동기화 적용 및 주의사항 (0) | 2023.09.21 |
---|---|
동시성 문제와 ThreadLocal (0) | 2023.09.21 |
Context Switching, Thread (0) | 2023.09.20 |
I/O - 다양한 IO객체들, 객체 직렬화 (0) | 2023.09.18 |
I/O - Decorator Pattern (0) | 2023.09.18 |