Java와 스레드 클래스의 효율적인 활용: Executor, 스레드 풀, Fork/Join

개요

Java에서 스레드를 사용하는 방법에 대해 이미 알고 있을 것입니다. 이전 글에서 `Thread` 클래스를 사용하여 작업을 실행하는 기본적인 코드를 살펴보았습니다. 다음은 그 예시입니다:

public static void main(String[] args) throws Exception {
    Runnable task = () -> System.out.println("작업 실행");
    Thread thread = new Thread(task);
    thread.start();
  }

이 코드는 스레드를 시작하는 데 필요한 기본적인 구조를 보여줍니다. 그러나 이러한 코드를 반복적으로 작성하는 것은 비효율적입니다. 이를 개선하기 위해 Java는 `Executor` 인터페이스를 제공합니다. 이 인터페이스를 사용하면 다음과 같이 코드를 더 간결하게 만들 수 있습니다:

public static void main(String[] args) throws Exception {
    Runnable task = () -> System.out.println("작업 실행");
    Executor executor = (runnable) -> {
      new Thread(runnable).start();
    };
    executor.execute(task);
  }

`Executor` 인터페이스는 `Runnable` 태스크를 실행할 수 있는 메커니즘을 제공합니다. 이 인터페이스의 하위 인터페이스인 `ExecutorService`는 추가적인 기능을 제공하며, 스레드 풀 관리와 같은 고급 기능을 포함합니다. `ExecutorService` 인터페이스는 Javadoc에서 자세히 설명되어 있으며, `java.util.concurrent.Executors` 팩토리를 통해 다양한 구현체를 생성할 수 있습니다.

ExecutorService

스레드를 직접 생성하는 대신, `ExecutorService`를 사용하면 작업을 제출하고 관리하는 것이 훨씬 쉽습니다. 예를 들어, 크기가 2인 고정 스레드 풀을 생성하고 작업을 제출할 수 있습니다:

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

  public static void main(String[] args) throws Exception {
    ExecutorService executorService = Executors.newFixedThreadPool(2);

    Future<?> future1 = executorService.submit(() -> {
      System.out.println("작업 1 실행: " + Thread.currentThread().getName());
      return null;
    });

    Future<?> future2 = executorService.submit(() -> {
      System.out.println("작업 2 실행: " + Thread.currentThread().getName());
      return null;
    });

    executorService.shutdown();
  }

위 코드에서 `ExecutorService`를 사용하여 크기가 2인 고정 스레드 풀을 생성하고, 두 개의 작업을 제출합니다. 각 작업은 현재 스레드의 이름을 출력한 후 종료됩니다. 마지막으로, `executorService.shutdown()`을 호출하여 스레드 풀을 종료합니다. 이렇게 하면 프로그램이 정상적으로 종료됩니다.

또한, `Executors` 팩토리는 다양한 유형의 스레드 풀을 생성하는 다른 메소드도 제공합니다. 예를 들어, 단일 스레드로 구성된 풀(`Executors.newSingleThreadExecutor()`)이나, 필요에 따라 스레드를 동적으로 생성하고 1분 동안 아이들 상태인 스레드를 제거하는 캐싱 풀(`Executors.newCachedThreadPool()`)을 생성할 수 있습니다.

태그: java Executor ExecutorService 스레드풀 Future

9월 20일 09:57에 게시됨