반응형

고수준 (High-Level) Concurrency 프로그래밍

  • 쓰레드를 만들고 관리하는 작업을 애플리케이션에서 분리.
  • 그런 기능을 Executors에게 위임.

 

Executors

  • 쓰레드 관리 및 생성을 담당하는 개체
  • Low-Level Concurrency 프로그래밍에서는 쓰레드의 생성과 관리를 위해 모두 코드로 직접 작성해야했다. 이제는 Executor에게 해야할 일을 전달해주면 쓰레드의 생성, 관리는 Executor를 통해 처리할 수 있다.
  • Executors가 하는 일
    • 쓰레드 만들기: 애플리케이션이 사용할 쓰레드 풀을 만들어 관리한다.
    • 쓰레드 관리: 쓰레드 생명 주기를 관리한다.
    • 작업 처리 및 실행: 쓰레드로 실행할 작업을 제공할 수 있는 API를 제공한다.
  • Blocking Queue
    • 쓰레드가 바빠서 처리하지 못한 작업들을 순서대로 쌓아 놓는다.

 

주요 인터페이스

  • Executor: execute(Runnable)
  • ExecutorService: Executor 상속 받은 인터페이스로, Callable도 실행할 수 있으며, Executor를 종료 시키거나, 여러 Callable을 동시에 실행하는 등의 기능을 제공한다.
  • ScheduledExecutorService: ExecutorService를 상속 받은 인터페이스로 특정 시간 이후에 또는 주기적으로 작업을 실행할 수 있다.

 

ExecutorService로 작업 실행하기

ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(() -> {
    System.out.println("Hello :" + Thread.currentThread().getName());
});

 

ExecutorService로 멈추기

executorService.shutdown(); // 처리중인 작업 기다렸다가 종료
executorService.shutdownNow(); // 당장 종료

 

Fork/Join 프레임워크

  • ExecutorService의 구현체로 손쉽게 멀티 프로세서를 활용할 수 있게끔 도와준다.

 

Executors 예제

public class Main {
    public static void main(String[] args){
        /*
            Executor 주의할 점
            - 작업을 수행 후, 다음 작업이 들어올 때 까지 계속 대기하기 때문에 프로세스가 종료되지 않는다. 그렇기 때문에 명시적으로 shutdown 해주어야 한다.
        */

        //static 팩토리 메소드 사용
        ExecutorService executorService = Executors.newSingleThreadExecutor(); //쓰레드를 하나만 쓰는 Executor
        //쓰레드 작업 수행
        executorService.submit(() -> {
            System.out.println("#######################");
            System.out.println("Hello " + Thread.currentThread().getName());
            System.out.println("#######################");
        });
        //프로세스 종료
        executorService.shutdown(); //gracefull shutdown : 현재 진행중인 작업은 끝까지 마치고 끝내는 것을 의미
//      executorService.shutdownNow(); // 현재 진행중인 작업을 끝까지 마치지 않고 끝내는 것을 의미

        ExecutorService executorService2 = Executors.newFixedThreadPool(2); //쓰레드를 두 개 쓰는 Executor
        //작업 5개 수행
        executorService2.submit(getRunnable("Hello"));
        executorService2.submit(getRunnable("Dev"));
        executorService2.submit(getRunnable("History"));
        executorService2.submit(getRunnable("Java"));
        executorService2.submit(getRunnable("Thread"));
        executorService2.shutdown();

        //주기적으로 어떤 작업을 실행하고 싶을 때 사용할 수 있는 Executor
        ScheduledExecutorService executorService3 = Executors.newSingleThreadScheduledExecutor();
        //3초 후에 작업 수행
        executorService3.schedule(getRunnable("Hello1"), 3, TimeUnit.SECONDS);
        //1초 대기 후 2초마다 작업 수행, interrupt 발생되면 종료됨
        executorService3.scheduleWithFixedDelay(getRunnable("Hello2"), 1, 2, TimeUnit.SECONDS);
//      executorService3.shutdown(); //interrupt 발생으로 인하여 주석 처리

    }

    private static Runnable getRunnable(String message) {
        return () -> System.out.println(message + Thread.currentThread().getName());
    }
}

[참고자료]

더 자바, Java 8, 백기선

Executors

반응형

+ Recent posts