반응형
1. Thread
정의
- CPU의 코어를 최대한 사용해서 많은 업무를 동시에 처리할 수 있게 도와 주는 것이다
특징
- 생성 관정에서 조금의 시간이 소요가 된다.
- 쓰래드 생성에 필요한 메모리 공간이 필요(stack 영역)
- thread 개수 제한을 두지 않기 때문에 너무 많은 thread를 생성하면 메모리 고갈과 같은 이슈가 발생할 수 있습니다
Thread 생성 방식(Task 등록)
- Runnable/Callable interface를 상속받은 객체를 실행하는 방식
- 관리의 편의 성을 더해주기위해서 Java 5부터 Thread pool을 사용 합니다
- 현재 대부분 Thread Pool과 ForkJoinPool을 응용하고 있습니다. thread 객체를 생성해서 task queue에 등록 후 하나씩 thread 와 매칭 시켜 ForkJoin과 같은 동작 메커니즘방식으로 처리하고 있습니다.
- 여기서 Task는 Runable이랑, Callable interface입니다.
- Runable : 일반 void 형태의 동작을 의미
- Callable : 반환 값이 존재하는 것들을 의미 -> 대부분 Runable interface를 상속받은 다른 adapter class에 등록해서 사용합니다
- ForkJoin: AdaptedCallable class에 등록 해서사용, FutureTask와 같이 Runable interface를 구현한 구현체에 adapter로 연결해서 사용함
Thread 동작 방식
- Forkjoin을 통해서 분할 정복방식으로 반복되는 연산을 여러 Thread에 분산키셔서 작업하는 방식
- Runnable에 있는 로직을 그냥 실행하는 방식
2. Thread Pool
정의
- java 5버전부터 도입
- 기존에 thread를 유저가 직접생성해서 구현해서 사용하였지만, java 5 부터는 concurrent 패키지가 포함되면서 thread를 미리 생성하고 관리하는 pool이 생겨남
- 쓰레드를 허용된 개수만큼만 생성하고 사용할 수 있도록 제약을 주는 것이다
특징
- 무제한 적으로 쓰레드 생성을 맊고 관리하기 위해서 사용
- JVM의 옵션등으로 제어할 수 없고 어플리케이션이 선택적으로 사용하는 방식이다
- 캐시 방식으로 생성하게 될 경우 요청이 들어 올 경우 자동으로 thread를 생성하고, 처리 완료가 된 후에 1분 정보 삭제가 되지 않습니다. 그리고 1분 내로 다른 요청이 들어오면 캐시로 삭제 되지 않은 thread 를 할당해주는 방식도 존재합니다.
구조
- Task Queue: Task의 요청을 받아서 저장하는 곳
- Manager: 실제 Thread를 생성하고 관리하는 곳
- 동작 부분: Task를 Queue에서 꺼내와서 실제 쓰레드를 동작 시켜 결과를 얻는 부분
3. ForkJoin Framework
정의
- java 7부터 도입됨
- 큰 업무를 작은 업무로 나누어 배분해서 일은 한 후에 일을 취합해서 실행 하는 실행 메커니즘 입니다.
- 분할 정복 알고리즘과 비슷하다고 생각하면 됩니다.
특징
- CPU를 최대로 활용하면서 동기화와 GC를 피할 수 있는 여러기법들이 사용됨
- 주로 반복적인 작업을 분할 정복을 통해서 취합하는 방식을 사용하기 때문에 stream 에서
parallel
을 사용할 경우 ForkJoin으로 데이터를 처리하도록 로직이 실행 됩니다.
실행 과정
- 큰 업무를 작은 단위로 쪼개서 사용
- 부모 쓰레드로 부터 처리로직을 복사하여 새로운 쓰레드에서 쪼개진 업무를 수행(Fork)
- 쪼개는 것을 반복하다가, 특정 쓰레드에서 더이상 Fork가 일어 나지 않고 업무가 완료 되면 그 결과를 부모 Thread에서 join하여 값을 취합
- 값을 취합 하는 것을 반복
핵심 기능(Work-Strealing)
- 기본적으로 newCachedThreadPool이나 newFixedThreadPool처럼 ExecutorService의 구현체 입니다.
- 기본적인 ExecutorServicer과 차이점은 work-stealing 알고리즘이 구현되어 있다는 점
- 이유 : cpu자원을 효율적으로 사용하기 위해서
- Idle상태의 CPU시간이 많아 지지 않도록 함
- 방식
- Task가 들어와서(submit) 처리 단계에서 Fork를 해 A, B로 나눠지게 됩니다.
- 2개의 thread(A,B)는 dequeue를 내부에 가지며 task를 등록해서 사용하게 됩니다.
- A,B중에 먼저 모든 처리를 끝낸 것이 존재할 경우 (예시 : A는 4개의 task 존재, B: 0개) cpu는 idle 상태가 존재하게 됩니다.
- 이때 B가 A의 테스크일부를 가져와서 처리하게 됩니다(stealing 훔치다)
- 이과정으로 cpu idle 시간을 줄일려고 노력 합니다.
반응형
'CS > Java' 카테고리의 다른 글
SOLID 원칙 (0) | 2022.02.06 |
---|---|
예외(Exception) (0) | 2022.01.20 |
함수형 프로그래밍 (0) | 2022.01.18 |
LocalDatetime, LocalDate, LocalTime (0) | 2022.01.12 |