046 Executor Service API

강의 메모 - ExecutorService API - 스레드 풀 실행 및 관리 #

개요 #

  • ExecutorService 는 비동기 작업을 실행하고 관리하기 위한 두 가지 메서드를 제공한다
    • void execute(Runnable r) – 작업을 제출하면 작업을 실행하고 종료한다
    • Future submit(Callable c) - 작업을 제출하면 작업을 실행함과 동시에 Future 를 반환한다. Future 에는 결과 값을 포함하고 있다 img.png

execute() vs submit() #

img_1.png

작업 중단 및 종료 #

  • ExecutorService 는 스레드 풀을 종료하기 위한 두 가지 메서드를 제공한다
    • void shutdown() - 정상적인 스레드 풀 종료
      • 이전에 제출된 작업은 실행하고 더 이상 새로운 작업은 수락하지 않습니다. 작업이 모두 완료되면 ExecutorService가 종료됩니다.
      • 실행중인 스레드를 강제로 인트럽트 하지 않기 때문에 인트럽트에 응답하는 작업이나 InterruptedException 예외 구문을 작성할 필요가 없다
    • List shutdownNow() - 강제적인 스레드 풀 종료
      • 이전에 제출된 작업도 취소하고 현재 실행중인 작업도 중단하려고 시도한다. 그리고 작업 대기 중이었던 작업 목록을 반환한다
      • 실행 중인 스레드를 강제로 인터럽트 하지만 해당 작업이 인터럽트에 응답하는 작업이 아닌 경우 작업 종료를 보장하지 않는다
        • 쓰레드풀 자체가 종료되지 않는다는게 아닌, 쓰레드 작업이 즉시 종료되지 않을 수 있다는 것
        • Future에 cancel() 하더라도 interrupt에 반응하는 작업이 있는 경우에 종료됨
        • interrupt()를 걸게됐을때 예외가 발생하게되면 종료
        • 쓰레드풀은 단지 intrrupt()만 걸어줄 뿐
      • 작업을 종료 하기 위해서는 Thread.isInterrupted() 나 sleep() 과 같은 인터럽트 관련 API 를 사용해야 한다
  • shutdown 후 작업을 제출할려고 시도하면 RejectedExecutionException 예외가 발생한다
  • shutdown 호출한 스레드는 실행 중인 작업이 종료될 때까지 기다리지 않고 바로 다음 라인을 실행한다. 만약 스레드가 메서드 호출 후 블록킹 되기 위해서는 awaitTermination 을 사용해야 한다
    • shutdown() 하라고 명령했을 뿐, 그 내부에서의 완료 여부는 알 수 없는데 그 이후 로직을 수행하므로 조심해야한다.

작업 종료 대기 및 확인 #

  • ExecutorService 는 작업 종료 대기 및 확인 위한 메서드를 제공한다
// 종료 요청 후 모든 작업이 실행 완료될 때까지 또는 타임아웃이 발생하거나 현재 스레드가 인터럽트될 때까지 블록된다
// 종료(shutdown, shutdownNow)가 완료되면 true를 반환하고 종료가 타임아웃 발생 전에 완료되지 않으면 false 를 반환한다
boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;

// ExecutorService 의 shutdown() 또는 shutdownNow() 메서드가 호출 후 종료 절차가 시작되었는지를 나타내며, 종료 절차 중이거나 완전히 종료된 상태일 때 true를 반환한다
// 종료 완료 여부가 아닌 신호를 보내면 true (shutdown, shutdownNow가 호출됐구나)
boolean isShutdown()

// ExecutorService 가 완전히 종료되어 더 이상 어떠한 작업도 수행하지 않는 상태인지를 나타내며, 모든 작업과 스레드가 완전히 종료된 후에 true를 반환한다 
// shutdown 또는 shutdownNow가 먼저 호출 되지 않은 경우에는 isTerminated 가 절대 true가 되지 않는다
boolean isTerminated();

종료 및 대기 흐름 #

img_2.png

API #

// Callable 작업을 실행하는 메서드로 작업의 결과를 나타내는 Future 를 반환하며 Future 에는 작업의 결과가 저장된다
Future<T> submit(Callable<T> task) // Future 에 결과 T 가 존재함

// Runnable 작업을 실행하는 메서드로 작업의 결과를 나타내는 Future 를 반환하며 Future 에는 지정된 결과가 저장된다
Future<T> submit(Runnable task, T result) // Future 에 결과 T 가 존재함

// Runnable 작업을 실행하는 메서드로 작업의 결과를 나타내는 Future 를 반환하며 Future 에는 아무런 결과가 존재하지 않는다
Future<?> submit(Runnable task); // Future 에 결과가 존재하지 않음