-
Java thread 와 프로세스에 대한 개념정리성장과정(dev)/Spring + Java + JPA 2025. 4. 5. 12:16
📘 Java 스레드의 주요 장점
- 멀티태스킹 지원
- 여러 작업을 동시에 실행할 수 있어 사용자 경험이 부드러워짐.
- 예: UI 응답 처리 + 백그라운드 데이터 처리
- CPU 자원 효율적 사용
- 멀티코어 CPU 환경에서 여러 스레드가 병렬로 실행되어 성능 향상 가능.
- 응답성 향상
- 무거운 작업(예: 파일 I/O, 네트워크 작업 등)을 별도 스레드로 처리하면 메인 스레드(UI 등)의 응답성 유지 가능.
- 공유 메모리 사용
- 같은 프로세스 내에서 스레드는 메모리를 공유하기 때문에, 프로세스 간 통신(IPC)보다 빠르고 간단함.
- 비용이 적음
- 새로운 프로세스를 생성하는 것보다 스레드 생성이 비용(시간과 자원) 면에서 훨씬 적음.
- 비동기 프로그래밍 용이
- 특정 작업을 백그라운드에서 처리하고, 완료 시 콜백 처리 등의 구조를 만들기 쉬움.
🎯 예를들어 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 구현 정책
- 비동기 아닌(non-async) 메서드에서 등록된 작업은:
- 현재 CompletableFuture를 완료시키는 스레드,
- 혹은 다른 완료 메서드 호출자 스레드가 실행함.
- 비동기(async) 메서드에서 Executor를 명시하지 않으면:
- ForkJoinPool.commonPool() 사용됨.
- 만약 해당 풀에서 병렬성 레벨이 2 이상 안 되면 → 새 스레드 생성.
- 모든 비동기 작업은 AsynchronousCompletionTask 마커 인터페이스의 인스턴스임.
- 모든 CompletionStage 메서드는 독립적으로 구현됨:
- 즉, 서브클래스에서 어떤 메서드를 오버라이드해도 다른 메서드의 동작에 영향 없음.
✅ Future 인터페이스 관련 정책
- FutureTask와 달리, 이 클래스는 직접 계산을 제어하지 않음.
- 취소는 예외적인 완료로 간주됨.
- cancel() 메서드는 내부적으로 completeExceptionally(new CancellationException()) 호출과 동일.
- isCompletedExceptionally() 메서드로 예외적으로 완료되었는지 확인 가능.
- 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)
'성장과정(dev) > Spring + Java + JPA' 카테고리의 다른 글
데이터베이스 데드락, 공유락, 베타락: 꼭 알아야 할 실무 필수 개념 (JPA) (0) 2024.12.13 nodeJS 개발자에서 다시 JAVA 개발자로, Java 9 ~ Java21 주요 변경사항들 (1) 2024.10.24 [intellij] jpa + gradle + junit4 테스트 중 에러발생 (0) 2020.11.26 [jpa] mariaDB 연동 (1) 2020.11.26 log4j sql로그 가독성 높이기 (0) 2020.09.18 - 멀티태스킹 지원