• 티스토리 홈
starryeye
  • 프로필사진
    starryeye
    • 분류 전체보기 (189)
      • C++ (17)
      • Java (24)
      • OOP (5)
      • Spring Reactive Stack (12)
        • Reactive Streams (3)
        • Netty (4)
        • Reactor (1)
        • Webflux (3)
        • DB, Cache 연동 (1)
      • Spring (90)
        • Core (17)
        • MVC (33)
        • Client (2)
        • Security (4)
        • DB, Cache 연동 (33)
      • DataBase (12)
        • RDBMS (2)
        • NoSQL (10)
      • Message Broker (6)
      • Web (4)
      • Network (4)
      • 대규모 시스템 설계 (15)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • [Java 정리] Thread 1
        2022년 08월 13일
        • starryeye
        • 작성자
        • 2022.08.13.:19
        반응형

        이미 알던 지식이지만, 기본으로 돌아가서.. Java의 관점에서 한번 정리해보자.

         

        프로세스와 쓰레드

         

        Process

        실행 중인 프로그램(어플리케이션)

        OS 커널로 부터 실행에 필요한 자원(가상 메모리)를 할당 받아 프로세스가 된다.

        프로그램을 수행하는데 필요한 데이터와 메모리 등의 자원 그리고 쓰레드로 구성되어 있다.

        하나의 프로세스 내에 쓰레드 개수는 제한 되어 있지 않지만,

        쓰레드에 개별적인 메모리 공간(호출 스택)을 할당해주므로 프로세스의 메모리 한계에 따라 정해진다.

         

        Thread

        프로세스의 자원을 이용해서 실제로 작업을 수행하는 것이 쓰레드이다.

        모든 프로세스는 최소한 하나 이상의 쓰레드가 존재한다.

        둘 이상의 쓰레드를 가진 프로세스를 멀티 쓰레드 프로세스라 한다.

         

        <참고>

        스케쥴러는 프로세스 또는 쓰레드 실행 순서와 실행 시간을 결정한다.

        OS는 프로세스의 스케줄러를 가진다.

        JVM은 쓰레드의 스케줄러를 가진다.

        하나의 자바프로그램은 하나의 프로세스이며 여러개의 쓰레드를 가질 수 있다.

         

         

        멀티태스킹과 멀티쓰레딩

         

        Multi-tasking

        OS가 여러 개의 프로세스를 동시에 실행시키는 것.

        (대부분의 OS는 이를 지원한다.)

         

        Multi-threading

        하나의 프로세스 내에서 여러 쓰레드가 동시에 작업을 수행하는 것이다.

        CPU의 코어가 한 번에 하나의 작업만 수행 할 수 있으므로,

        실제로 동시에 처리되는 작업의 개수는 코어의 개수와 일치한다.

        (Spring Webflux가 코어당 하나 또는 두개의 쓰레드를 두고 작업한다.)

        (반면 Spring MVC는 여러개의 쓰레드를 쓰레드 풀에 두고 사용한다.)

         

        멀티 쓰레딩 장점

        CPU 사용률 업!

        자원을 효율적으로 사용

        사용자 응답성 업!

        작업 분리로 인한 코드 간결성 업!

         

        멀티 쓰레딩 단점

        동기화, 데드락 문제 해결해야 한다.

        동기화는 락의 개념, 데드락은 자원 접근 우선순위를 두고 사용으로 간단하게 회피 가능하긴 하다.

        하지만, 성능 상의 문제가 다시 생겨버림..

        (구체적인 해결법 추후 포스팅..)

         

         

        쓰레드 구현

         //Thread클래스를 상속 받은 경우
        class MyThread1 extends Thread {
            public void run() {
                //로직 구현
            }
        }
        
        //Runnable 인터페이스를 구현한 경우
        class MyThread2 implements Runnable {
            public void run() {
                //로직 구현
            }
        }
        
        public static void main(String args[]) {
            
            //Thread클래스를 상속 받은 경우의 인스턴스 생성
            MyThread1 t1 = new MyThread1();
            
            //Runnable 인터페이스를 구현한 경우의 인스턴스 생성
            Runnable r = new MyThread2();
            Thread t2 = new Thread(r);
            //한줄로 Thread t2 = new Thread(MyThread2());
        }

         

        Runnable 인터페이스

        Runnable 인터페이스는 단순히 run 메서드만 정의되어있다..

        따라서, Runnable 인터페이스를 구현하는 방법으로 쓰레드 동작 로직(run)을 구현할 때,

        run 메서드 내부에서 Thread 클래스의 메서드를 사용하고 싶을 땐...

        static Thread currentThread()

        위의 static 메서드인 currentThread 메서드를 사용하여 현재 쓰레드의 참조를 얻어와야지

        Thread 클래스의 메서드를 사용할 수 있다.

        class MyThread implements Runnable {
            public void run() {
                //currentThread()로 현재 쓰레드의 참조를 얻었기 때문에
                //getName() 메서드를 사용할 수 있다.
                System.out.println(Thread.currentThread().getName());
            }
        }

         

         

        쓰레드의 실행, run() 메서드와 start() 메서드

         

        쓰레드를 실행시키기 위해서는 start() 메서드를 호출 해야한다.

        run() 메서드 호출은 단순히 선언된 run() 메서드를 호출하는 것.. 그 이상 그 이하도 아니다.

         

        start()

        새로운 쓰레드가 작업을 실행하는데 필요한 새로운 호출 스택을 생성한 후, run() 메서드를 호출한다.

        위 그림에서 볼 수 있듯이, start() 메서드를 호출 하면 새로운 호출 스택이 생성되고

        해당 호출 스택에서 run()메서드가 실행 되는 것을 볼 수 있다.

         

        따라서, 앞으로...

        main 쓰레드와 새로 생성된 쓰레드가 별도의 호출 스택을 가지고

        스케줄러(JVM)이 정한 실행 순서와 실행 시간에 의해 번갈아 가며 실행 될 것이다.

         

        프로세스의 종료 시점?

        main 쓰레드의 호출 스택만 존재 했을 때는 main 쓰레드의 호출 스택이 모두 비워지면 프로세스가 종료 되었다.

        하지만..

        멀티 쓰레드 환경에서는

        하나의 쓰레드의 호출 스택만 남아 있어도 프로세스는 종료되지 않는다.

        (여기서 쓰레드는 사용자 쓰레드를 말한다. 데몬 쓰레드 X)

         

         

        싱글 쓰레드와 멀티 쓰레드

        CPU 코어는 한번에 하나의 쓰레드를 돌릴 수 있다.

         

        CPU가 싱글 코어일 때를 상상해보자..

         

        싱글 쓰레드로 두개의 작업을 돌릴 때..

        -> 첫번째 작업이 끝나면 두번째 작업을 시작한다.

         

        두개의 쓰레드로 각각 한개의 작업, 총 두개의 작업을 돌릴 때..

        -> 두개의 쓰레드이지만 코어가 하나이므로 concurrency 하게 두개의 작업이 동시에 진행 되는 것 처럼 보이게 한다.

        -> 두개의 작업은 절대로 겹치지 않는다.

        -> 싱글 쓰레드 일 때 보다 시간이 더 오래걸린다. 왜냐하면 context switching 비용이 들기 때문이다.

         

        CPU가 멀티 코어(2개 이상)를 가질 때를 상상해보자..

         

        두개의 쓰레드로 각각 한개의 작업, 총 두개의 작업을 돌릴 때..

        -> 싱글 코어일 때 보다 훨씬 빠른 작업 처리를 볼 수 있다.

        -> 멀티 코어이므로 두개의 작업은 겹친다. (parallelism)

        그러나.. 예를 들어...

        두개의 작업이 동일한 자원에 접근해야 할 경우 race condition(경쟁 상태)이 되므로

        완벽한 parallelism 을 달성 할 수 없다.

        하지만..

        두개의 작업이 서로 다른 자원에 접근한다면 굉장히 효율적으로 프로그래밍 된 케이스이다.

        반응형

        'Java' 카테고리의 다른 글

        [Java 정리] Thread 3  (0) 2022.08.19
        [Java 정리] Thread 2  (0) 2022.08.13
        [Java 정리] String, final, Immutable  (0) 2022.08.05
        [Java 정리] Garbage Collector 1  (0) 2022.07.30
        [Java 정리] 내부 클래스  (0) 2022.07.28
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바