우주먼지
Published 2023. 3. 1. 15:03
Single & Multi Thread Languages/Java

💡 Single & Multi Thread

싱글코어 스레드

수행시간의 쉬운 측정을 위해 new String 사용 (작업 수행속도 낮춤)

public class CountThreadTimeMillis {
    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.print("소요시간 1:" + (System.currentTimeMillis() - startTime));

        for (int i=0; i<300; i++) {
            System.out.printf("%s", new String("|"));
        }
        System.out.print("소요시간 2:" + (System.currentTimeMillis() - startTime));
    }
}

출력 결과

thread.CountThreadTimeMillis
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------소요시간 1:31||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||소요시간 2:47

멀티코어 스레드

두개의 스레드가 작업을 하나씩 나누어서 작업을 수행하는 예시

  • 두개의 스레드로 작업하는데도 시간이 오래 걸리는 이유는 2가지 이다.
    • 스레드를 번갈아 가며 실행하기 때문에 컨텍스트 스위칭에 소요되는 시간
    • 한 스레드가 화면에 출력할 동안 다른 스레드는 기다리는 대기시간
public class MultiCoreThread {
    static long startTime = 0;

    public static void main(String[] args) {
        CountThreadMillis t1 = new CountThreadMillis();
        t1.start();

        startTime = System.currentTimeMillis();

        for (int i=0; i<300; i++) {
            System.out.printf("%s", new String("-"));
        }
        System.out.print("소요시간 1:" + (System.currentTimeMillis() - MultiCoreThread.startTime));
    }

    public static class CountThreadMillis extends Thread {
        public void run() {
            for (int i=0; i<300; i++) {
                System.out.printf("%s", new String("|"));
            }
            System.out.print("소요시간 2:" + (System.currentTimeMillis() - MultiCoreThread.startTime));
        }
    }
}

Single Core 출력 결과

thread.multicore.MultiCoreThread
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|||||||||||||||||--------------------------------------------------------------------------------------------------------------|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||소요시간 1:32소요시간 2:32

MultiCore 출력 결과

thread.multicore.MultiCoreThread
----||||||||||----||||||||||||--||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||---------------------------------------------------|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||-------------------------------|||||||||||||||||||||||------------------------------------------------------------------------------|||||||||||||||||||||||||||||||||||||---------------------------------------------------------------------------------------|||||||||||||||||||||||||||||||||||||||||||||||-------------------------------------------소요시간 2:32소요시간 1:47

💡 차이점

싱글코어

  • 멀티스레드라도 하나의 코어가 번갈아 가며 작업한다.

멀티코어

  • 멀티스레드로 두 작업 수행 시, 동시에 두 스레드가 실행될 수 있으므로
    두 작업이 겹치는 부분이 발생한다.

그래서 화면(console)이라는 자원을 놓고 두 스레드가 경쟁하게 된다.

위의 결과는 실행할때마다 다른결과가 나온다.

그 이유는 프로세스는 OS의 프로세스 스케쥴러의 영향을 받기 때문이다.

JVM의 스레드 스케쥴러에 의해 어떤 스레드가 얼마동안 실행될 것인지 결정하는것과 같이
프로세스도 OS의 프로세스 스케쥴러에 의해 실행순서 & 시간이 결정되기 때문에
매 순간 상황에 따라 프로세스에게 할당되는 실행시간이 일정하지 않고 스레드에게
할당되는 시간 역시 일정하지 않게 된다.

자바가 OS독립적이라고 하지만 OS 종속적인 부분도 존재하며 스레드도 그 중 하나이다.


💡 두 스레드가 서로 다른 자원을 사용하는 작업의 경우

싱글스레드 프로세스보다 멀티 스레드 프로세스가 더 효율적이다.

예를 들면,

사용자로부터 데이터를 입력받는 작업, 네트워크로 파일을 주고받는 작업, 프린터로 파일을 출력하는 작업과 같이 외부기기와의 입출력을 필요로 하는 경우가 이에 해당한다.

만약 사용자로부터 입력받는 작업(A)과 화면에 출력하는 작업(B)을 하나의 스레드로 처리한다면

사용자가 입력을 마칠 때까지 아무일도 못하고 기다리기만 해야 한다.

이 때, 두개의 스레드로 작업을 한다면 사용자의 입력을 기다리는 동안 다른 스레드가 작업을 처리할 수 있기 때문에 보다 효율적인 CPU 사용이 가능하다.

싱글스레드 예시

public class SingleThreadIO {
    public static void main(String[] args) throws Exception {
        String input = JOptionPane.showInputDialog("아무 값이나 입력하세요.");
        System.out.println("입력하신 값은 " + input + "입니다.");

        for (int i=10; i>0; i--) {
            System.out.println(i);
            try {
                Thread.sleep(1000); // 1초간 시간 지연
            } catch (Exception e) {}
        }
    }
}

출력 결과

입력하신 값은 abc입니다.
10
9
8
7
6
5
4
3
2
1

 

멀티스레드 예시

public class MultiThreadIO {
    public static void main(String[] args) throws Exception {
        TempThread t1 = new TempThread();
        t1.start();

        String input = JOptionPane.showInputDialog("아무 값이나 입력하세요.");
        System.out.println("입력하신 값은 " + input + "입니다.");
    }

    public static class TempThread extends Thread {
        public void run() {
            for (int i=10; i>0; i--) {
                System.out.println(i);
                try {
                    sleep(1000);
                } catch (Exception e) {}
            }
        }
    } // run()
}

출력 결과

thread.multicore.MultiThreadIO
10
9
8
입력하신 값은 abc입니다.
7
6
5
4
3
2
1

'Languages > Java' 카테고리의 다른 글

Stream 생성  (0) 2023.03.17
Stream  (0) 2023.03.01
Thread  (0) 2023.03.01
J2EE  (0) 2023.02.20
Lambda  (0) 2023.02.19
profile

우주먼지

@o귤o

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그