JAVA

Executor 프레임워크

도원좀비 2025. 3. 12. 20:19

1️⃣ Executor 프레임워크란?

기존에는 new Thread()로 직접 쓰레드를 만들었지만,
➡ 쓰레드 생성 비용이 크고, 너무 많은 쓰레드가 생성되면 시스템이 느려질 수 있다

✅ 이를 해결하기 위해 Executor 프레임워크를 사용하면 쓰레드를 효율적으로 관리할 수 있


2️⃣ Executor 프레임워크의 주요 개념

Executor 종류 설명
newFixedThreadPool(n) 고정된 개수의 쓰레드를 유지 (CPU 코어 수에 맞춰 조정 가능)
newCachedThreadPool() 필요할 때 새로운 쓰레드를 생성하지만, 기존 쓰레드 재사용
newSingleThreadExecutor() 하나의 쓰레드만 실행 (직렬 실행)
newScheduledThreadPool(n) 일정 시간마다 작업 실행 (타이머 기능)

Executor 프레임워크는 쓰레드를 직접 만들지 않고도 자동으로 관리해준다


3️⃣ FixedThreadPool (고정된 쓰레드 풀)

정해진 개수만큼의 쓰레드를 생성하여 실행 (CPU 코어 수에 맞춰 설정 가능)

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FixedThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3); // 3개의 쓰레드 풀 생성

        for (int i = 1; i <= 10; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println(Thread.currentThread().getName() + " 작업 실행: " + taskId);
                try {
                    Thread.sleep(1000); // 작업 실행 시간 시뮬레이션
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        executor.shutdown(); // 모든 작업이 끝나면 종료
    }
}

✅ 쓰레드 3개를 재사용하면서 10개의 작업을 실행
✅ 쓰레드가 과도하게 생성되지 않으므로 성능을 최적화할 수 있음


4️⃣ CachedThreadPool (동적으로 쓰레드 관리)

쓰레드 개수를 자동으로 조절하며 필요하면 추가 쓰레드를 생성하고, 사용 후 재사용

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CachedThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();

        for (int i = 1; i <= 10; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println(Thread.currentThread().getName() + " 작업 실행: " + taskId);
                try {
                    Thread.sleep(1000); // 작업 실행 시간 시뮬레이션
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        executor.shutdown();
    }
}

필요한 만큼 쓰레드를 생성하고, 사용이 끝나면 자동으로 정리됨
짧은 작업이 많은 경우 적절하지만, 너무 많은 쓰레드가 생성될 수도 있음


5️⃣ SingleThreadExecutor (하나의 쓰레드만 사용)

하나의 쓰레드로 모든 작업을 순차적으로 실행 (직렬 실행)
멀티쓰레드가 필요 없는 작업에 적합

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SingleThreadExecutorExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newSingleThreadExecutor();

        for (int i = 1; i <= 5; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println(Thread.currentThread().getName() + " 작업 실행: " + taskId);
            });
        }

        executor.shutdown();
    }
}

멀티쓰레드가 필요 없는 경우 유용함
로그 작성, 파일 저장 등 순차적으로 실행해야 하는 작업에 적합


6️⃣ ScheduledThreadPool (예약된 작업 실행)

일정 시간마다 반복적인 작업을 실행할 때 사용 (타이머 역할)

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledThreadPoolExample {
    public static void main(String[] args) {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

        Runnable task = () -> System.out.println("스케줄된 작업 실행: " + System.currentTimeMillis());

        scheduler.scheduleAtFixedRate(task, 1, 2, TimeUnit.SECONDS); // 1초 후 시작, 2초마다 실행
    }
}

타이머, 주기적인 데이터 백업, 모니터링 작업 등에 적합
CPU 사용량을 조절하면서 일정한 간격으로 작업을 실행할 수 있음

Executor 정리

종류 특징  
FixedThreadPool 고정된 개수의 쓰레드를 유지 웹 서버, 대량의 요청 처리
CachedThreadPool 필요할 때 쓰레드를 생성하고 재사용 짧고 가벼운 작업이 많을 때
SingleThreadExecutor 하나의 쓰레드로 작업을 순차 실행 로그 작성, 순차적 처리
ScheduledThreadPool 특정 시간 간격으로 작업 실행 타이머, 주기적인 백업

 

'JAVA' 카테고리의 다른 글

가상 쓰레드 (Virtual Threads)  (0) 2025.03.12
CompletableFuture (비동기 처리)  (1) 2025.03.12
쓰레드 동기화 (Synchronization)  (3) 2025.03.11
쓰레드(Thread)  (0) 2025.03.11
Java Stream API 주요 메서드 정리  (2) 2025.02.28