안녕하세요 알통몬입니다. 공감 및 댓글은 포스팅 하는데 아주아주 큰 힘이 됩니다!! 포스팅 내용이 찾아주신 분들께 도움이 되길 바라며 더 깔끔하고 좋은 포스팅을 만들어 나가겠습니다^^
|
블로킹 방식 작업 완료 통보 :
Future 객체는 작업 완료 시까지 기다렸다가 최종 결과를 얻는데 사용.
=> Future는 지연 완료 객체라고 함.
Future()의 get()을 호출하면 스레드가 작업 시까지 블로킹 되었다가 작업 완료 후 처리 결과 리턴
==> 블로킹을 사용하는 작업 완료 통보 방식임.
리턴타입 메서드명(매개변수) 설명
V get() 작업이 완료 시까지 블로킹되었다가 처리 결과 V리턴
V get(long timeout, TimeUnit unit) timeout 시간 전에 작업이 완료되면 결과 V를 리턴,
작업이 완료되지 않으면 TimeoutException을 발생
리턴 타입 V는 submit(Runnable task, V result) 두 번째 매개값인 V 타입이거나
submit(Callable<V> task)의 Callable 타입 파라미터 V 타입입니다.
아래는 submit() 별로 Future의 get() 메서드가 리턴하는 값이 무엇인지 보여줍니다.
메서드 작업 처리 완려 후 리턴 타입 작업 처리 도중 예외 발생
submit(Runnable task) future.get() -> null future.get() -> 예외 발생
submit(Runnable task, Integer result) future.get() -> int 타입 값 future.get() -> 예외 발생
submit(Callable<String> task) future.get() -> String 타입 값 future.get() -> 예외 발생
Future를 이용한 블로킹 방식의 작업 완료 통보에서 주의할 점은 작업을 처리하는 스레드가
작업을 완료하기 전까지는 get() 메서드가 블로킹되므로 다른 코드를 실행할 수 없습니다.
UI를 변경하고 이벤트를 처리하는 스레드가 get() 메서드를 호출하면 작업을 완료하기 전까지
UI를 변경할 수도 없고 이벤트를 처리할 수도 없게 됩니다.
때문에 get() 메서드를 호출하는 스레드는 새로운 스레드이거나 스레드풀의 또 다른 스레드가 되어야 합니다.
새로운 스레드 생성하여 호출
new Thread(new Runnable() {
@Override
public void run() {
try {
future.get();
} catch( Exception e) {
e.printStackTrace();
}
}
}).start();
스레드 풀의 스레드가 호출
executorService.submit(new Runnable() {
@Override
public void run() {
try {
future.get();
} catch(Exception e) {
e.printStackTrace();
}
}
});
Future 객체는 작업 결과를 얻기 위한 get() 말고도 다른 메소드들을 제공
리턴 타입 메서드명(매개변수) 설명
boolean cancel(boolean mayInterruptRunning) 작업 처리가 진행 중이라면 취소시킴
boolean isCanceled() 작업 취소되었는지 여부 리턴
boolean isDone 작업 처리 완료 여부 리턴
cancel()은 작업을 취소하고 싶을 때 호출,
작업 시작 전이면 매개값에 상관없이 작업 취소 후 true 리턴
작업이 진행중이면 매개값이 true일 경우에만 작업 스레드를 interrupt.
작업이 완료되었을 경우, 어떤 이유로 인해 취소될 수 없다면 cancel()은 false를 리턴.
isCanceled()은 작업이 완료되기 전에 작업이 취소되었을 경우에먼 true를 리턴.
isDone()은 작업이 정상적, 예외, 취소 등 어떤 이유에서건 완료되었다면 true를 리턴.
리턴 값이 없는 작업 완료 통보
리턴 값이 없는 작업 => Runnable 객체로 생성하면 됨
Runnable task = new Runnable() {
@Override
public void run() {
//코드
}
};
submit(Runnable)을 이용해 작업 처리 요청을 하면 됨.
결과 값이 없더라도 Future 객체를 리턴하는데 이유는 작업 처리가 정상적으로 됐는지 아니면
도중에 예외가 발생했는지를 확인하기 위함.
Future f = executorService.submit(task);
작업 처리가 정상적으로 완료 됐다면 Future의 get()은 null 리턴,
하지만 스레드가 작업 처리 도중 interrupt 되면
InterruptedException을 발생시키고 작업 처리 도중 예외가 발생하면
ExecutionException을 발생시킵니다. 따라서 아래처럼 예외처리 코드가 필요합니다.
ex)
try {
future.get();
} catch( InterruptedException e) {
} catch( ExecutionException e) {
}
리턴 값이 있는 작업 완료 통보
스레드 풀의 스레드가 작업 완료 후 애플리케이션 처리 결과를 얻어야 할 경우
작업 객체를 Callable로 생성.
ex)
Callable<T> task = new Callable<T> {
@Override
public T call() throws Exception {
return T;
}
};
Callable도 Runnable과 같이 ExecutorService의 submit()호출로 작업 처리 요청을 하면 됨,=.
submit()은 작업 큐에 Callable 객체를 저장하고 즉시 Future<T>를 리턴
이 때 T는 call() 메서드가 리턴하는 타입.
Future<T> f = executorService.submit(task)
스레드 풀의 스레닥 Callable 객체의 call()을 모두 실행하고 T타입의 값을 리턴하면
Future<T>의 get()은 블로킹이 해제되고 T 타입 값을 리턴.
try {
T result = future.get();
} catch( InterruptException e) {
} catch( ExecutionException e) {
}
이상입니다.
'자바' 카테고리의 다른 글
JAVA 자바 ThreadPool 자바 스레드 풀 : 콜백 방식 작업 완료 통보 CallBack (0) | 2017.03.17 |
---|---|
자바 스레드풀 ThreadPool : 블로킹 방식 작업 완료 통보 => 작업 처리 결과 외부에 저장, 작업 완료 순 통보 (0) | 2017.03.17 |
자바 스레드풀 ThreadPool : 스레드 풀 작업 생성과 작업 처리 요청 (0) | 2017.03.17 |
자바 스레드풀 ThreadPool : 스레드풀 생성과 스레드풀 종료 (0) | 2017.03.17 |
JAVA Thread 자바 스레드 : 스레드 그룹 이름 얻기 / 스레드 그룹 생성 / 스레드 그룹의 일괄 inerrupt() /// 스레드 그룹 생성 / 스레드 그룹의 일괄 inerrupt() (0) | 2017.03.15 |