1. 싱글쓰레드와 멀티쓰레드
싱글 쓰레드 프로세스와 멀티 쓰레드 프로세스의 차이를 봐보자. 두 개의 작업을 하나의 쓰레드(th1)로 처리하는 경우와 두 개의 쓰레드(th1, th2)로 처리하는 경우를 가정해보자. 하나의 쓰레드로 두 작업을 처리하는 경우는 한 작업을 마친 후에 다른 작업을 시작하지만, 두 개의 쓰레드로 작업을 하는 경우에는 짧은 시간 동안 2개의 쓰레드가 번갈아가면서 작업을 수행해서 동시에 두 작업이 처리되는 것처럼 보인다.
하나의 쓰레드로 두 개의 작업을 수행한 시간과 두개의 쓰레드로 작업을 수행한 시간은 거의 같다. 오히려 쓰레드를 2개로 만들어서 사용한 경우가 더 오래걸린다. 그 이유는 쓰레드간의 컨텍스트 스위칭 비용이 추가로 걸리기 때문이다.
작업 전환을 할 때는 현재 진행중인 작업의 상태를, 예를 들면 다음에 실행해야할 위치(PC, 프로그램 카운터) 등의 정보를 저장하고 읽어오는 시간이 소요된다. 참고로 쓰레드의 스위칭에 비해 프로세스 스위칭 비용은 더 많은 정보를 저장해야해서 오래걸린다.
다음 예제를 통해서 싱글 쓰레드로 수행했을 때의 시간을 봐보자
package thread;
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();
System.out.println("소요시간1:" + (System.currentTimeMillis() - startTime));
for(int i=0; i < 300; i++)
System.out.printf("%s", new String("|"));
System.out.println();
System.out.println("소요시간2:" + (System.currentTimeMillis() - startTime));
}
}
[실행 결과]
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
소요시간1:29
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
소요시간2:46
다음으로 두개의 쓰레드를 생성해서 수행한 결과를 봐보자. 이전 예제와 달리 아주 짧은 시간동안 번갈아 가면서 실행되었으며 거의 동시에 작업이 완료되었음을 알 수 있다. 실행 시간은 컴퓨터의 성능에 따라 다를 수 있다.
package thread;
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();
System.out.println("소요시간1:" + (System.currentTimeMillis() - ThreadEx5.startTime));
}
static 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();
System.out.println("소요시간2: " + (System.currentTimeMillis() - ThreadEx5.startTime));
}
}
}
--||||||||||||||||||||||||||||||||----------------|||||||||||||||||||||||||||||||||||||||||||||||||----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|||||||||||||||||||||||||||||||||||||||||||------------------------------------------------------------------------------------||||||||||||||||||--------------------------
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
소요시간2: 19
소요시간1:17
두 쓰레드가 서로 다른 자원을 사용하는 작업의 경우에는 싱글 쓰레드 프로세스보다 멀티 쓰레드 프로세스가 더 효율적이다. 예를 들면 사용자로부터 데이터를 입력 받는 작업, 네트워크로 파일을 주고 받는 작업, 프린터로 파일을 출력하는 작업과 같이 외부기기와의 입출력을 필요로하는 경우가 이에 해당한다.
2. 쓰레드의 우선순위
쓰레드는 우선순위라는 속성을 가지고 있다. 이 우선순위에 따라서 쓰레드가 얻는 실행시간이 달라진다. 쓰레드가 수행하는 작업의 중요도에 따라 쓰레드의 우선순위를 서로 다르게 지정하여 특정 쓰레드가 더 많은 작업시간을 갖도록 할 수 있다.
예를 들어 파일전송기능이 있는 메신저의 경우, 파일 다운로드를 처리하는 쓰레드보다 채팅 내용을 전송하는 쓰레드의 우선순위가 더 높아야 사용자가 채팅하는데 불편함이 없을 것이다. 대신 파일 다운로드 작업에 걸리는 시간은 더 길어진다.
쓰레드의 우선 순위는 쓰레드를 생성한 쓰레드로부터 상속 받는다. main 메서드를 수행하는 쓰레드는 우선순위가 5이므로 main 메서드 내에서 생성하는 쓰레드의 우선순위는 자동으로 5가 된다.
public class ThreadEx8 {
/**
* 멀티코어에서는 쓰레드의 우선순위에 상관없이 작업이 비슷하게 완료됨.
* @param args
*/
public static void main(String[] args) {
ThreadEx8_1 th1 = new ThreadEx8_1();
ThreadEx8_2 th2 = new ThreadEx8_2();
th2.setPriority(7);
System.out.println("Priority of th1(-) : " + th1.getPriority());
System.out.println("Priority of th2(-) : " + th2.getPriority());
th1.start();
th2.start();
}
static class ThreadEx8_1 extends Thread {
@Override
public void run() {
for(int i=0; i < 300; i++) {
System.out.print("-");
for(int x=0; x < 100000000; x++); // 작업 지연용 for문
}
}
}
static class ThreadEx8_2 extends Thread {
@Override
public void run() {
for(int i=0; i < 300; i++) {
System.out.print("|");
for(int x=0; x < 100000000; x++); // 작업 지연용 for문
}
}
}
}
참고로 싱글코어에서는 쓰레드 우선순위가 영향을 주지만, 멀티코어에서는 비슷하게 작업이 완료될 것이다.
Reference
http://www.yes24.com/Product/Goods/24259565
'Java' 카테고리의 다른 글
[Java] Thread(쓰레드) - 5 (0) | 2022.06.02 |
---|---|
[Java] Thread(쓰레드) - 4 (0) | 2022.06.02 |
[Java] Thread(쓰레드) - 2 (0) | 2022.05.30 |
[Java] Thread(쓰레드) - 1 (0) | 2022.05.30 |
[Java] 코딩 컨밴션 (Code Conventions ) (0) | 2021.04.11 |