쓰레드를 무한으로 늘리게 되면 어떤 문제가 발생하나?
- 성능 저하
- 쓰레드도 하나의 자원이므로 계속적으로 소모되면 자원고갈로 인해 메모리풀로 인해 서버가 다운될 수 있다.
- 서버 입장에서 가장 중요한 것은 서버가 다운되지 않고 안정적으로 운영되는 것이다.
서버를 어떻게 안정적으로 운영할까?
쓰레드를 미리 만들어 놓고 재사용하는 방식으로 사용한다 == 쓰레드 풀.
왜 쓰레드 풀을 사용할까?
서버가 모든 요청에 대해 Thread를 매번 생성하게되면 성능상 문제가 발생할 수 있다.
ThreadPool을 적용해 일정 수의 작업을 동시 처리하도록 한다.
ThreadPoolExecutor
자바에서는 ThreadPoolExecutor라는 클래스를 지원해주는데 다음과 같은 생성자들이 존재한다.
//ThreadPoolExecutor 생성자
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
//Creating a threadPoolExecutor
int corePoolSize = 10;
int maxPoolSize = 15;
long keepAliveTime = 6000;
ExecutorService es = new threadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue < Runnable > ());
◾ int corePoolSize
-기본 풀 사이즈를 의미
- 실행할 최소 Thread 수
◾ int maximumPoolSize
-최대 지원 Thread 수
◾ long keepAliveTime
- 쓰레드 미사용 시 제거 대기 시간
-corePoolSize보다 쓰레드가 많아졌을 경우 maximumPoolSize까지 쓰레드가 생성되는데 keepAliveTime시간만큼 유지했다가 다시 corePoolSize로 유지되는 시간을 의미한다.
◾ TimeUnit unit
- keepAliveTime 값의 시간단위 (eg. milliseconds, seconds.. )
◾ BlockingQueue <Runnable> workQueue
-요청된 작업들이 저장될 큐 : 작업 대기열 관리
- corePoolSize보다 작업 쓰레드가 많아졌을 경우, 남는 쓰레드가 없을 경우, workQueue에서 대기한다.
* 여기서 maximumPoolSize 옵션에 유의해야하는데, maximumPoolSize 이 사용되는 시점이다.
단순히 생각하기로는 corePoolSize만큼 쓰레드들에게 task를 할당하고, 이 이상 task가 들어오면 maximumPoolSize 까지 쓰레드를 추가하면서 task를 실행시키다가 maximumPoolSize까지 쓰레드가 꽉 차면 그때부터 workQueue에 task를 보관한다고 생각할 수 있지만, javadoc 문서를 확인하면 이러한 순서로 동작하지 않는다.
즉, corePoolSize > maximumPoolSize > workQueue 순이 아니라,
corePoolSize > workQueue > maximumPoolSize 순으로 동작한다는 말이다.
corePoolSize의 모든 thread가 busy 상태인 경우 새로운 task는 maximumPoolSize로 확장되는것이 아니라 workQueue 내에서 대기한다. workQueue 까지도 다 차면 그때 maximumPoolSize로 확장하는 것이다.
그러므로 workQueue의 크기를 크게 잡거나, 혹은 크기지정을 하지 않는다면 쓰레드 풀은 maximumPoolSize로 확장하지 않기 때문에 실질적으로는 maximumPoolSize는 효과가 없어지게 된다.
◾ RejectedExecutionHandler handler
- 작업요청 거부 시 처리할 핸들러
'Back-end > JAVA,Spring' 카테고리의 다른 글
[java] Try-with-resource 문이란? 자동 자원반납. (0) | 2021.05.20 |
---|---|
[Spring] @RequestBody / @ResponseBody 어노테이션 이란? (8) | 2021.05.06 |
[java] Thread Pool 쓰레드 풀이란 ? (6) | 2021.04.08 |
[JAVA] Try-Catch문이란? 예외처리하기/예외던지기 (0) | 2020.12.11 |
[JAVA]에러/예외처리란? Error/Exception Handling (0) | 2020.12.10 |