Back-End/SpringBoot

[SpringBoot] Executors.newFixedThreadPool() 코드의 이슈(자원 반환해주기)

코딩콩 2023. 5. 27. 15:21

Executors.newFixedThreadPool() 사용목적

Executors.newFixedThreadPool() 메서드는 지정된 개수의 스레드가 있는 고정 크기의 스레드 풀을 생성할 수 있도록 하고, 이 스레드 풀은 비동기 작업을 처리하는 데 사용한다.

아래와 같이 CompletableFuture과 함께 사용했다.

private void scrapExecuteAsync(List<Request> requestList) {
    ExecutorService executor = Executors.newFixedThreadPool(6);
    List<CompletableFuture<Void>> futures = new ArrayList<>();

    requestList.forEach(request -> {
        CompletableFuture<Void> future = CompletableFuture.runAsync(() ->
            scrapService.create(request), executor);
        futures.add(future);
    });

    CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
    executor.shutdown();
}

 

생긴 이슈

그런데 이 코드를 사용하여 배포 후 일주일 후 이슈가 생겨버렸다.

스레드 수가 2천개를 넘고,,, 메모리가 가득차 서버가 혼자 죽었다 새로 생겼다 반복한 것을 발견했다.

결론, 주의사항

executor.shutdown();
private void scrapExecuteAsync(List<Request> requestList, CardSalesConnectionStore connectionStore) {
    ExecutorService executor = Executors.newFixedThreadPool(6);
    List<CompletableFuture<Void>> futures = new ArrayList<>();

    requestList.forEach(request -> {
        CompletableFuture<Void> future = CompletableFuture.runAsync(() ->
            cardSalesApprovalDataCreateService.create(request, connectionStore), executor);
        futures.add(future);
    });

    CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
    executor.shutdown();
}

사용 후 shutdown() 이나 shutdownNow()를 사용하여 꼭!꼭! 스레드 반환해주기.

shutdown()을 써서 보는 비동기 처리가 완료된 후에 스레드를 반환해주도록 했다.