Java 8 (4) - 자바 Concurrent / Executors / Callable / Future

자바 Concurrent 프로그래밍
[ Concurrent 소프트웨어 ]
- 동시에 여러 작업을 할 수 있는 소프트웨어
- ex) 한글작업을 하면서 유튜브로 음악듣기
[ Java에서 지원하는 Concurrent 프로그래밍 ]
- 멀티 프로세싱 -->
ProcessBuilder 사용
- 멀티 쓰레딩 -->
Thread, Runnable, Executors, Callable 등 사용
[ Thread의 주요 기능 ]
- sleep
- 현재 쓰레드 멈추기
자원에 대한 락을 놓아주지는 않고, 제어권을 넘겨주는 것 (데드락 조심해야 함)
- interupt
- 다른 쓰레드를 깨워서
interruptedException 을 발생시키는 것
예외를 발생시킨 후 종료하거나 다른일을 수행하게 할 수 있다 (설계 나름)
- join
해당 쓰레드 작업이 끝날 때 까지 기다리게 하는 것
쓰레드의 순서를 제어할 때 사용할 수 있음
[ 그래서 ? ]
Java에서 멀티 쓰레드를 통해 Concurrent를 처리할 때 개발자가 쓰레드를 직접 하나하나 관리하기는 힘듬
- 이렇게
쓰레드를 만들고 관리하고 작업을 처리하는 것을 Executors 에게 위임해서 처리한다
Executors
[ 개념 ]
- 고수준 (
High-Level) Concurrency 프로그래밍
쓰레드를 만들고 관리하는 작업을 애플리케이션에서 분리해서 관리
[ 역할 ]
- 쓰레드 만들기 :
애플리케이션에서 사용될 쓰레드를 만들거나, 쓰레드 풀을 통해 관리
- 쓰레드 관리 :
쓰레드의 생명 주기를 관리
- 작업 처리 및 실행 :
쓰레드로 작업을 수행하기 위한 API를 제공
[ 주요 인터페이스 ]
- Executor.execute(
Runnable) or Executor.submit(Runnable)
- Executor.shutdown() :
할일을 모두 마치고 종료
- Executor.shutdownNow() :
지금 당장 종료
- ExecutorService
Executor 를 상속 받은 인터페이스
Runnable과 Callable 모두 실행 가능
Executor 를 종료하거나, 여러 Callable을 동시에 실행할 수도 있음
- ScheduledExecutorService
ExecutorService 를 상속받은 인터페이스
특정 시간 이후에 또는 주기적으로 작업을 수행하게 하는 스케줄 기능 
Callable & Future
[ Callable ]
설명
Runnable과 같은 쓰레드 생성에 사용되는 인터페이스
Runnable은 반환(return) 타입이 void --> 처리 결과를 받을 수 X
Callable은 반환(return) 타입이 객체 --> 처리 결과를 받을 수 O
[ Future ]
설명
비동기적인 작업의 현재 상태를 조회하거나 결과를 가져오기 위한 객체
Runnable / Callable의 상태를 조회하거나 결과를 확인하기 위해 사용
시간이 걸릴 수 있는 작업을 Future 내부에 작성하고,
호출자 스레드가 결과를 기다리는 동안 다른 유용한 작업을 할 수 있음
--> 실행을 맞기고 미래 시점에 결과를 얻는 것으로 이해 가능
처리 결과에 대한 콜백을 정의할 수 없어서 이후에 CompletableFuture이 등장함
.get() 을 통해서 블로킹(Blocking) 콜을 수행
: .get()을 통해서 결과를 확인하기 위해 결과를 기다린다 --> 블로킹(Blocking)
[ Future 주요 인터페이스 ]
get() & isDone()

.get()
- 블로킹(
Blocking) 콜 : 작업의 처리 결과를 get 하기 위해서 결과를 기다리게 된다(Blocking 상태)
.isDone()
작업이 완료되었으면 true / 아니면 false 반환
cancel()

.cancel()
- 파라미터 값
- true :
작업 interupt하고 종료
- false :
작업이 끝날 때 까지 대기 후 종료
- 결과 값
- true :
정상적으로 cancel 수행 O
- false :
정상적으로 cancel 수행 X
invokeAll()

.invokeAll()
동시에 실행한 작업 중 제일 오래 걸리는 작업만큼 시간 소요
모든 결과가 수행된 뒤 처리되어야 할 때 사용
invokeAny()

.invokeAny()
여러 작업 중 하나라도 먼저 응답이 오면 끝난다
동시에 실행한 작업 중 제일 짧게 걸리는 작업 만큼 시간 소요
같은 일을 여러 쓰레드를 통해 수행한 뒤 먼저 응답이 오면 사실상 나머지는 필요가 X
블로킹 콜 로 동작