하나의 쓰레드로 두 작업을 처리하는 경우는 한 작업을 마친 후에 다른 작업을 시작하지만, 두 개의 쓰레드로 작업하는 경우에는 짧은 시간동안 2개의 쓰레드가 번갈아 가면서 작업을 수행해서 동시에 두 작업이 처리되는 것처럼 느껴지게 한다.

F23846F5-6475-4871-987A-B21C009FC6E6.jpeg

하지만 두 개의 쓰레드로 작업한 시간이 싱글 쓰레드로 작업한 시간보다 더 걸리게 되는데 그 이유는 쓰레드간의 작업 전환(context switching) 에 시간이 걸리기 때문이다.

그래서 싱글 코어에서 단순히 CPU 만을 사용하는 계산작업이라면 오히려 멀티쓰레드보다 싱글쓰레드로 프로그래밍하는 것이 더 효율적이다.

싱글 코어 vs 멀티 코어

동일하게 두 개의 쓰레드로 작업해도 멀티 코어가 더 시간이 오래 걸린다. 하나는 두 쓰레드가 번갈아가면서 작업을 처리하기 때문에 쓰레드간의 작업전환시간이 소요되기 때문이고, 하나는 한 쓰레드가 화면에 출력하고 있는 동안 다른 쓰레드는 출력이 끝나기를 기다려야 하는데, 이때 발생하는 대기시간 때문이다.

B847D9B7-EE63-4412-A0CA-539190A18D54.jpeg

싱글 코어인 경우에는 멀티 쓰레드라도 하나의 코어가 번갈아가면서 작업을 수행하는 것이므로 두 작업이 절대 겹치지 않는다. 그러나, 멀티 코어에서는 멀티 쓰레드로 두 작업을 수행하면, 동시에 두 쓰레드가 수행될 수 있으므로 화면(console) 이라는 자원을 놓고 두 쓰레드가 경쟁하게 된다.

여러 쓰레드가 여러 작업을 동시에 진행하는 것을 병행(concurrent) 라고 하고, 하나의 작업을 여러 쓰레드가 나눠서 처리하는 것을 병렬(parallel) 이라고 한다.

위의 결과는 실행할 때마다 다른 결과를 얻을 수 있는데 그 이유는 실행 중인 예제프로그램(프로세스)이 OS 의 프로세스 스케쥴러의 영향을 받기 때문이다. JVM 의 쓰레드 스케쥴러에 의해서 어떤 쓰레드가 얼마동안 실행될 것인지 결정되는 것과 같이 프로세스도 프로세스 스케쥴러에 의해서 실행 순서와 실행 시간이 결정되기 때문에 매 순간 상황에 따라 프로세스에게 할당되는 실행시간이 일정하지 않고 쓰레드에게 할당되는 시간 역시 일정하지 않게 된다. 그래서 쓰레드가 이러한 불확실성을 가지고 있다는 것을 염두해 두어야 한다.

JVM 의 종류에 따라 쓰레드 스케쥴러의 구현방법이 다를 수 있기 때문에 멀티 쓰레드로 작성된 프로그램을 다른 종류의 OS 에서도 충분히 테스트해 볼 필요가 있다.

두 쓰레드가 서로 다른 자원을 사용하는 작업의 경우에는 싱글 쓰레드 프로세스보다 멀티 쓰레드 프로세스가 더 효율적이다.