ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java thread 와 프로세스에 대한 개념정리
    성장과정(dev)/Spring + Java + JPA 2025. 4. 5. 12:16

    📘  Java 스레드의 주요 장점

    1. 멀티태스킹 지원
      • 여러 작업을 동시에 실행할 수 있어 사용자 경험이 부드러워짐.
      • 예: UI 응답 처리 + 백그라운드 데이터 처리
    2. CPU 자원 효율적 사용
      • 멀티코어 CPU 환경에서 여러 스레드가 병렬로 실행되어 성능 향상 가능.
    3. 응답성 향상
      • 무거운 작업(예: 파일 I/O, 네트워크 작업 등)을 별도 스레드로 처리하면 메인 스레드(UI 등)의 응답성 유지 가능.
    4. 공유 메모리 사용
      • 같은 프로세스 내에서 스레드는 메모리를 공유하기 때문에, 프로세스 간 통신(IPC)보다 빠르고 간단함.
    5. 비용이 적음
      • 새로운 프로세스를 생성하는 것보다 스레드 생성이 비용(시간과 자원) 면에서 훨씬 적음.
    6. 비동기 프로그래밍 용이
      • 특정 작업을 백그라운드에서 처리하고, 완료 시 콜백 처리 등의 구조를 만들기 쉬움.

    🎯 예를들어 UI 렌더링과 로직 처리를 분리할 수 있음.

     

    📘  멀티태스킹 지원, 뭐가 좋은데? 어차피 자원은 한정적이잖아

    어차피 CPU 코어 수는 정해져 있고, 스레드를 수십 개 띄운다고 해서 물리적으로 동시에 전부 돌아가는 건 아니다. 그럼에도 불구하고 장점은 "자원을 최대한 활용하고, 사용자 경험을 개선"할 수 있기 때문

     

    1. CPU가 노는 시간을 줄여준다 (I/O 대기 시간 활용)

    • 예: A 작업이 네트워크 요청 중이라 기다리는 동안 CPU는 놀고 있음.
    • 이때 B 스레드가 다른 작업을 하게 하면, 그 대기 시간을 다른 작업으로 메꿀 수 있음.
    • "진짜 동시 실행"은 아니더라도 효율은 올라감.

    2. 사용자 경험(UX) 개선

    • 예: 메인 스레드가 화면 UI 처리 중인데, 백그라운드에서 파일 다운로드 같이 무거운 작업이 같이 돌아감.
    • 단일 스레드였다면? UI 멈춤, 앱 멈춤 느낌, 최악엔 "응답 없음".
    • 멀티스레드는 사용자는 계속 앱을 조작하고, 백그라운드에서 다른 일 처리 가능.

    3. 논리적 동시성으로 효율적인 설계 가능

    • 하나의 스레드에 모든 걸 몰아 넣으면 설계 복잡도 폭발.
    • 역할 분리(예: 요청 처리 스레드, 로깅 스레드, 작업 처리 스레드)를 통해 유지보수성 향상.

    4. 멀티코어 환경에서 실제 병렬 처리 가능

    • 코어가 4개 이상인 CPU에선 스레드들이 물리적으로 진짜 동시에 돌아감.
    • CPU 성능을 100% 활용 가능 ➜ 고성능 처리에 유리.

     

    📘  Java 에서 스레드를 명시적으로 구현해주지 않으면 프로그램은 기본적으로 "단일 스레드(single-thread)" 환경에서 실행돼요.

    기본적으로 main 함수는 단일스레드 이지만

    우리가 직접 구현하지 않아도 Java 내부에서 스레드가 만들어져 돌아가는 경우 -> 자동스레드

    • 웹서버 (예: Tomcat) -클라이언트 요청마다 스레드를 만들어 처리
    • 스레드 풀 사용 - ExecutorService로 관리되는 스레드
    • 비동기 처리 -CompletableFuture.runAsync() 같은 경우도 내부적으로 스레드 사용
    • GUI 프로그램 (예: JavaFX, Swing) -이벤트 디스패치 스레드(EDT)가 따로 작동

     

    📘 CompletableFuture API 설명 정리 (요약)

      주로 언제 사용하나요?

    CompletableFuture는 비동기 프로그래밍을 깔끔하고 유연하게 하고 싶을 때 주로 사용돼요. 특히 콜백 지옥 피하고, 비동기 작업 간 연결(연쇄), 에러 처리, 병렬 실행 등을 다룰 때 진가를 발휘합니다.

     

    ✅ 기본 개요

    • Future처럼 값을 설정해서 완료할 수 있으며,
    • CompletionStage처럼 완료 시 실행될 함수나 작업을 지정할 수 있음.

    ✅ 완료 메서드 관련

    • complete, completeExceptionally, cancel 같은 완료 관련 메서드는
      여러 스레드가 동시에 호출하더라도 단 하나만 성공함.

    ✅ CompletionStage 구현 정책

    1. 비동기 아닌(non-async) 메서드에서 등록된 작업은:
      • 현재 CompletableFuture를 완료시키는 스레드,
      • 혹은 다른 완료 메서드 호출자 스레드가 실행함.
    2. 비동기(async) 메서드에서 Executor를 명시하지 않으면:
      • ForkJoinPool.commonPool() 사용됨.
      • 만약 해당 풀에서 병렬성 레벨이 2 이상 안 되면 → 새 스레드 생성.
      • 모든 비동기 작업은 AsynchronousCompletionTask 마커 인터페이스의 인스턴스임.
    3. 모든 CompletionStage 메서드는 독립적으로 구현됨:
      • 즉, 서브클래스에서 어떤 메서드를 오버라이드해도 다른 메서드의 동작에 영향 없음.

    ✅ Future 인터페이스 관련 정책

    1. FutureTask와 달리, 이 클래스는 직접 계산을 제어하지 않음.
      • 취소는 예외적인 완료로 간주됨.
      • cancel() 메서드는 내부적으로 completeExceptionally(new CancellationException()) 호출과 동일.
      • isCompletedExceptionally() 메서드로 예외적으로 완료되었는지 확인 가능.
    2. CompletionException으로 예외가 완료된 경우:
      • get()과 get(long, TimeUnit)은 내부 예외를 담은 ExecutionException을 던짐.
      • 대신, join()과 getNow()는 CompletionException 자체를 직접 던짐 (사용자 편의성을 위해 제공됨).

     

     

    📘 Javascript 의 멀티스레드

    Javascript 는 싱글스레드언어이지만 Java thred 를 사용하려면 Web worker 나 Worker Thread (Node.js 10.5.0 이상) 를 사용해서 멀티스레드를 구현할 수 있다. 

     

     

    📘 자바기준에서 프로세스와 스레드 차이는? 

    ✔ 프로세스 (Process)

    • Java에서 ProcessBuilder나 Runtime.getRuntime().exec()으로 외부 프로그램을 실행하면 새로운 프로세스가 만들어짐.
    • 예: Java에서 Python 스크립트를 실행한다면, 그건 별개의 프로세스.

    ✔ 스레드 (Thread)

    • Java에서는 Thread 클래스를 이용해서 같은 프로세스 안에서 동시 실행 흐름을 만들 수 있음.

     

    🎯 메모리 공유 차이

    • 스레드끼리는 힙 메모리 공유 ➜ 전역 변수, 객체 공유 가능
    • 프로세스끼리는 메모리 분리 ➜ 데이터를 주고받으려면 파일, 소켓, 파이프 등 IPC 필요

     

    📘 Java에서 프로세스를 사용하는 경우

    • MSA : 로그인서비스, 결제서비스, 검색 서비스 각각 다른 프로세스로 구동하는 경우
      • 참고로, 이전 회사에서는 프로세스별로 쪼개는 것이 아닌, 별도의 서버로 올려서 사용했었다. MSA 는 일반적으로 컨테이너가 분리된다. 구조적인 관점으로만 보기 !!
    • Java 웹서버는 backend (비지니스로직), Python 은 AI 처리를 하는 경우

     

    📘 Java에서 스레드를 사용하는 경우

    • 같은 서비스/기능 내에서 동시에 여러 작업을 처리해야 할 때
    • 사용자 요청 처리, 백그라운드 작업, 비동기 이벤트 등

    💡 예시

    • Java 웹 서버(Tomcat, Jetty 등)는 클라이언트 요청마다 새 스레드 생성
    • 스프링에서 @Async, CompletableFuture 같은 비동기 처리
    • 스레드 풀을 통한 워커 스레드 관리 (ExecutorService)
Designed by Tistory.