Future은 비동기 계산의 결과를 나타냅니다. 이를 통해 계산이 완료되었는지 확인하고, 완료를 기다리며 계산 결과를 검색할 수 있는 메서드가 제공됩니다.
계산이 완료된 경우에만 get 메서드를 사용하여 결과를 검색할 수 있으며, 필요한 경우 준비될 때까지 블로킹됩니다.
작업을 취소하려면 cancel 메서드를 사용합니다.
작업이 정상적으로 완료되었는지 아니면 취소되었는지를 확인하기 위한 추가적인 메서드도 제공됩니다. 한번 계산이 완료되면 작업을 취소할 수 없습니다.
작업의 결과를 사용하지 않고 취소 가능성을 위해 Future를 사용하려면 Future<?> 형식을 선언하고 기본 작업의 결과로 null을 반환할 수 있습니다.
Future 메서드
- cancel(boolean) : 작업을 취소하려고 시도합니다. 작업이 이미 완료된 경우이거나 취소를 했을 경 실패합니다. 성공하면 작업이 실행되지 않습니다. 작업이 이미 시작되었으면 매개변수를 통해 작업을 실행할지 중지할지 결정됩니다. ca메서드가 실행된 후 isDone 메서드를 호출하면 항상 true를 반환합니다.
- isCancelled() : 작업이 정상적으로 취소되면 true 반환합니다.
- isDone() : 작업이 완료되면 true를 반환합니다. 정상적인 종료 또는 cancel되거나 예외상태로 true를 반환됩니다.
- get() : 작업이 완료될때까지 기다린 후 결과를 반환합니다.
- get(long, TimeUnit) : 시간만큼 대기했다가 안되면 TimeoutException을 보냅니다.
cancel 예시
Runnable task = () -> {
System.out.println("task 실행");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
};
ExecutorService es = Executors.newFixedThreadPool(1);
Future<?> future = es.submit(task);
future.cancel(false);
es.shutdown();
cancel 매개변수에 false를 넘겨주면서 작업이 시작되었으면 실행됩니다. 그래서 인터럽트가 걸리지 않습니다. 하지만 true일때는 작업이 시작되도 종료되기 때문에 인터럽트가 실행됩니다.
isCancelled 예시
Runnable task = () -> {
System.out.println("task 실행");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("task 끝");
};
ExecutorService es = Executors.newSingleThreadExecutor();
Future<?> future = es.submit(task);
boolean isCancel = future.isCancelled();
System.out.println("isCancel:" + isCancel); // false
es.shutdown();
cancel를 했을 경우
Runnable task = () -> {
System.out.println("task 실행");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("task 끝");
};
ExecutorService es = Executors.newSingleThreadExecutor();
Future<?> future = es.submit(task);
future.cancel(false);
boolean isCancel = future.isCancelled();
System.out.println("isCancel:" + isCancel); // true
es.shutdown();
isDone 예시
Runnable task = () -> {
System.out.println("task 실행");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("task 끝");
};
ExecutorService es = Executors.newSingleThreadExecutor();
Future<?> future = es.submit(task);
boolean isDone = future.isDone();
System.out.println("isDone:" + isDone); // false
es.shutdown();
ExecutorService es = Executors.newSingleThreadExecutor();
Future<?> future = es.submit(task);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
boolean isDone = future.isDone();
System.out.println("isDone:" + isDone); // true
task가 1초정도 걸리니 2초뒤에 isDone을 호출하면 true가 나옵니다.
ExecutorService es = Executors.newSingleThreadExecutor();
Future<?> future = es.submit(task);
future.cancel(false);
boolean isDone = future.isDone();
System.out.println("isDone:" + isDone); //true
es.shutdown();
cancel를 하면 무조건 isDone은 true가 나옵니다.
get 예시
Callable<String> task = () -> {
System.out.println("task 실행");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "task 끝";
};
ExecutorService es = Executors.newSingleThreadExecutor();
Future<String> future = es.submit(task);
String result = null;
try {
result = future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
System.out.println("result:" + result); //task 끝
es.shutdown();
Callable를 통해 비동기적으로 리턴값을 주면 future.get에서 값을 기다려서 리턴을 해줍니다.
Callable<String> task = () -> {
System.out.println("task 실행");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "task 끝";
};
ExecutorService es = Executors.newSingleThreadExecutor();
Future<String> future = es.submit(task);
String result = null;
try {
result = future.get(1, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
System.out.println("result:" + result);
es.shutdown();
task는 5초 걸리는데 get에 최대 시간을 1초로 잡고 코드를 실행시켜서 TimeoutException이 나면서 result로 초기값인 null이 나옵니다.
'JAVA > 스레드' 카테고리의 다른 글
[JAVA] ScheduledExecutorService 인터페이스 (0) | 2023.10.18 |
---|---|
[JAVA] Executors 클래스 (0) | 2023.10.17 |
[JAVA] ExecutorService 인터페이스 (1) | 2023.10.11 |
[JAVA] Executor 인터페이스 (0) | 2023.10.10 |
[JAVA] 스레드 풀의 개념과 필요성 (0) | 2023.10.06 |