티스토리 뷰
스레드와 높은 수준의 추상화
단일 CPU가 여러 사용자를 지원할 수 있는데 이는 운영체제가 각 사용자에 프로세스를 할당하기 때문
두 사용자가 자신만의 공간에 있다고 생각할 수 있도록 가상 주소 공간을 각 프로세스에 제공
운영체제는 주기적으로 번갈아가며 각 프로세스에 CPU를 할당함
프로세스는 운영체제에 한개 이상의 스레드로 같은 주소 공간을 공유하는 태스크를 동시에 실행
네 개의 코어를 가진 CPU에서 이론적으로는 병렬로 실행하여 실행 속도를 네배 향상시킬 수 있음
자바 스트림으로 병렬성을 달성
long sum = Arrays.stream(stats).parallel().sum();
스트림을 이용해 스레드 사용 패턴을 추상화
Executor와 스레드 풀
Java 5는 Executor 프레임워크와 ThreadPool을 통해 스레드의 힘을 높은 수준으로 끌어올리는
태스크 제출과 실행을 분리할 수 있는 기능을 제공
스레드의 문제
Java 스레드는 직접 운영체제 스레드에 접근
운영체제 스레드는 제한되어 있어 운영체제가 지원하는 스레드 수를 초과하지 않도록 주의
주어진 프로그램에서 사용할 최적의 스레드 수는 사용할 수 있는 하드웨어 코어의 개수에 따라 달라짐
스레드 풀이 더 좋은 이유
ExecutorService는 태스크를 제출하고 나중에 결과를 수집할 수 있는 인터페이스를 제공
newFixedThreadPool 같은 팩토리 메서드 중 하나를 이용해 스레드 풀을 만들어 사용
워커 스레드라 불리는 nThreads를 포함하는 ExecutorService를 만들고 이들을 스레드 풀에 저장
스레드 풀에서 사용하지 않은 스레드로 제출된 태스크를 먼저 온 순서대로 실행
태스크 실행이 종료되면 스레드 풀로 반환
하드웨어에 맞는 수의 태스크를 유지함과 수 천개의 태스크를 스레드 풀에 오버헤드 없이 제출할 수 있음
스레드 풀이 나쁜 이유
초과로 제출된 태스크는 큐에 저장되며 이전에 태스크 중 하나가 종료되기 전까지 할당하지 않음
I/O를 기다리는 블록 상황에서 태스크가 워커 스레드에 할당된 상태를 유지하지만 아무 작업도 하지 않음
데드락에 걸릴 수도 있음
중첩되지 않은 메서드 호출 (비동기 메서드)
사용자의 메서드 호출에 의해 스레드가 생성되고 메서드를 벗어나 계속 실행되는 동시성
메서드 호출자에 기능을 제공하도록 메서드가 반환된 후에도 만들어진 태스크 실행이 계속되는걸 비동기 메서드
비동기 메서드 위험성
스레드 실행은 메서드를 호출한 다음의 코드와 동시에 실행되므로 데이터 경쟁 문제를 주의
실행 중이던 스레드가 종료되지 않은 상황에서 main() 메서드가 반환하면?
- 애플리케이션을 종료하지 못하고 모든 스레드가 실행을 끝날 때까지 기다림
- 애플리케이션 종료를 방해하는 스레드를 강제종료 시키고 애플리케이션을 종료
자바 스레드는 setDaemon() 메서드를 이용해 데몬, 비데몬으로 구분
데몬 스레드는 애플리케이션이 종료될 때 강제 종료되므로 데이터 일관성을 파괴하지 않음
main() 메서드는 모든 비데몬 스레드가 종료될 때까지 프로그램을 종료하지 않고 기다림
'Java' 카테고리의 다른 글
[Java] 리팩터링 (1) | 2023.11.26 |
---|---|
[Java] DateTimeFormatter uuuu vs yyyy (1) | 2023.11.23 |
[Java] Executor (0) | 2023.11.20 |
[Java] EnumSet, EnumMap (0) | 2023.10.29 |
[Java] 날짜, 시간 API (0) | 2023.10.18 |