[Java] Thread(쓰레드) - 3

Java / / 2022. 5. 31. 00:23

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의 정석 - YES24

최근 7년동안 자바 분야의 베스트 셀러 1위를 지켜온 `자바의 정석`의 최신판. 저자가 카페에서 12년간 직접 독자들에게 답변을 해오면서 초보자가 어려워하는 부분을 잘 파악하고 쓴 책. 뿐만 아

www.yes24.com

 

'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
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기