Language/Java

싱글쓰레드와 멀티쓰레드, 싱글코어와 멀티코어

kimjingyu 2023. 9. 21. 00:24
728x90

병행(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)을 차지하고자 하는 작업이었다면, 두 쓰레드가 서로 다른 자원을 사용하는 작업의 경우에는 멀티쓰레드가 더 효율적이다. 예를들어, 사용자의 입력을 기다리는 동안 다른 쓰레드가 작업을 처리할 수 있기때문이다.

 

인용

자바의 정석

728x90