Java : Future - API使用例
Future (Java SE 19 & JDK 19) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様のおともにどうぞ。
概要
Futureはインタフェースは、非同期処理の結果を表します。
- 処理が完了したかどうかのチェック
- 完了までの待機
- 結果の取得
などを行うためのメソッドが用意されています。
主に ExecutorService の submit メソッドの戻り値として取得して使います。
// 基準となる時刻
final long current = System.nanoTime();
// 基準となる時刻からの差分を秒として取得
final DoubleSupplier elapsedTime = () -> (System.nanoTime() - current) / 1000000000.0;
try (final var executorService = Executors.newSingleThreadExecutor()) {
final var future = executorService.submit(() -> {
try {
System.out.printf("task : start (%f sec.)%n", elapsedTime.getAsDouble());
TimeUnit.SECONDS.sleep(2);
return "abcd";
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.printf("task : end (%f sec.)%n", elapsedTime.getAsDouble());
}
});
TimeUnit.SECONDS.sleep(1);
System.out.printf("future.get ... (%f sec.)%n", elapsedTime.getAsDouble());
final var ret = future.get();
System.out.printf("future.get OK! (%f sec.)%n", elapsedTime.getAsDouble());
System.out.println("ret = " + ret);
}
// 結果
// ↓
//task : start (0.002537 sec.)
//future.get ... (1.003706 sec.)
//task : end (2.004116 sec.)
//future.get OK! (2.004768 sec.)
//ret = abcd
メソッド
boolean cancel (boolean mayInterruptIfRunning)
// 基準となる時刻
final long current = System.nanoTime();
// 基準となる時刻からの差分を秒として取得
final DoubleSupplier elapsedTime = () -> (System.nanoTime() - current) / 1000000000.0;
class Task implements Callable<String> {
private final String name;
Task(String name) {
this.name = name;
}
@Override
public String call() {
try {
System.out.printf("%s : task start (%f sec.)%n", name, elapsedTime.getAsDouble());
TimeUnit.SECONDS.sleep(2);
return "abcd";
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.printf("%s : task end (%f sec.)%n", name, elapsedTime.getAsDouble());
}
}
}
try (final var executorService = Executors.newSingleThreadExecutor()) {
System.out.println("submit A");
final var futureA = executorService.submit(new Task("A"));
TimeUnit.SECONDS.sleep(1);
System.out.println("submit B");
final var futureB = executorService.submit(new Task("B"));
System.out.println("-- cancel tasks --");
final var retA = futureA.cancel(false);
System.out.printf("cancel A : ret = %b (%f sec.)%n", retA, elapsedTime.getAsDouble());
final var retB = futureB.cancel(false);
System.out.printf("cancel B : ret = %b (%f sec.)%n", retB, elapsedTime.getAsDouble());
}
System.out.println("-- end --");
// 結果
// ↓
//submit A
//A : task start (0.002960 sec.)
//submit B
//-- cancel tasks --
//cancel A : ret = true (1.014476 sec.)
//cancel B : ret = true (1.014648 sec.)
//A : task end (2.016125 sec.)
//-- end --
// ※mayInterruptIfRunning = false では割込みは発生しません。
// また、サブミットだけで開始されていなかったタスクBは、開始されないまま終了します。
final long current = System.nanoTime();
final DoubleSupplier elapsedTime = () -> (System.nanoTime() - current) / 1000000000.0;
try (final var executorService = Executors.newSingleThreadExecutor()) {
final var future = executorService.submit(() -> {
try {
System.out.printf("task start (%f sec.)%n", elapsedTime.getAsDouble());
TimeUnit.SECONDS.sleep(2);
return "abcd";
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.printf("task end (%f sec.)%n", elapsedTime.getAsDouble());
}
});
TimeUnit.SECONDS.sleep(1);
System.out.printf("cancel! (%f sec.)%n", elapsedTime.getAsDouble());
final var ret = future.cancel(true);
System.out.printf("cancel ret = %b%n", ret);
}
// 結果
// ↓
//task start (0.003275 sec.)
//cancel! (1.004838 sec.)
//Interrupted!
//task end (1.005646 sec.)
//cancel ret = true
// ※mayInterruptIfRunning = true は割込みを発生させます。
final long current = System.nanoTime();
final DoubleSupplier elapsedTime = () -> (System.nanoTime() - current) / 1000000000.0;
try (final var executorService = Executors.newSingleThreadExecutor()) {
final var future = executorService.submit(() -> {
try {
System.out.printf("task start (%f sec.)%n", elapsedTime.getAsDouble());
TimeUnit.SECONDS.sleep(2);
return "abcd";
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.printf("task end (%f sec.)%n", elapsedTime.getAsDouble());
}
});
// タスクが完了するのを待ちます。
System.out.println("get = " + future.get());
final var ret = future.cancel(true);
System.out.printf("cancel ret = %b (%f sec.)%n", ret, elapsedTime.getAsDouble());
}
// 結果
// ↓
//task start (0.002477 sec.)
//task end (2.009747 sec.)
//get = abcd
//cancel ret = false (2.011178 sec.)
// ※すでに終了しているタスクに対して cancel すると false を返します。
default Throwable exceptionNow ()
try (final var executorService = Executors.newSingleThreadExecutor()) {
final var futures = new ArrayList<Future<String>>();
futures.add(executorService.submit(() -> "abc"));
futures.add(executorService.submit(() -> "XYZ"));
futures.add(executorService.submit(() -> {
throw new IllegalStateException("Fail!");
}));
futures.add(executorService.submit(() -> "1234"));
final var results = futures.stream()
.filter(f -> f.state() == Future.State.SUCCESS)
.map(Future::resultNow)
.toList();
System.out.println("results = " + results);
final var exceptions = futures.stream()
.filter(f -> f.state() == Future.State.FAILED)
.map(Future::exceptionNow)
.toList();
System.out.println("exceptions = " + exceptions);
}
// 結果
// ↓
//results = [abc, XYZ, 1234]
//exceptions = [java.lang.IllegalStateException: Fail!]
V get ()
try (final var executorService = Executors.newSingleThreadExecutor()) {
final var future = executorService.submit(() -> {
try {
System.out.println("task start");
TimeUnit.SECONDS.sleep(2);
return "abcd";
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.println("task end");
}
});
TimeUnit.SECONDS.sleep(1);
System.out.println("-- get start --");
final var ret = future.get();
System.out.println("-- get end --");
System.out.println("ret = " + ret);
}
// 結果
// ↓
//task start
//-- get start --
//task end
//-- get end --
//ret = abcd
try (final var executorService = Executors.newSingleThreadExecutor()) {
final var future = executorService.submit(() -> {
try {
System.out.println("task start");
TimeUnit.SECONDS.sleep(2);
throw new IllegalStateException("Fail!");
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.println("task end");
}
});
TimeUnit.SECONDS.sleep(1);
try {
System.out.println("-- get start --");
final var ret = future.get();
System.out.println("-- get end --");
System.out.println("ret = " + ret);
} catch (ExecutionException e) {
System.out.println("ExecutionException! : " + e.getMessage());
}
}
// 結果
// ↓
//task start
//-- get start --
//task end
//ExecutionException! : java.lang.IllegalStateException: Fail!
try (final var executorService = Executors.newScheduledThreadPool(2)) {
final var future = executorService.submit(() -> {
try {
System.out.println("task start");
TimeUnit.SECONDS.sleep(3);
return "abcd";
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.println("task end");
}
});
// 2秒後にキャンセルします。
executorService.schedule(() -> {
System.out.println("future.cancel");
future.cancel(true);
}, 2, TimeUnit.SECONDS);
try {
System.out.println("-- get start --");
final var ret = future.get();
System.out.println("-- get end --");
System.out.println("ret = " + ret);
} catch (CancellationException e) {
System.out.println("CancellationException!");
}
}
// 結果
// ↓
//task start
//-- get start --
//future.cancel
//Interrupted!
//CancellationException!
//task end
V get (long timeout, TimeUnit unit)
try (final var executorService = Executors.newSingleThreadExecutor()) {
final var future = executorService.submit(() -> {
try {
System.out.println("task start");
TimeUnit.SECONDS.sleep(2);
return "abcd";
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.println("task end");
}
});
TimeUnit.SECONDS.sleep(1);
try {
System.out.println("-- get start --");
final var ret = future.get(3, TimeUnit.SECONDS);
System.out.println("-- get end --");
System.out.println("ret = " + ret);
} catch (TimeoutException e) {
System.out.println("TimeoutException!");
}
}
// 結果
// ↓
//task start
//-- get start --
//task end
//-- get end --
//ret = abcd
try (final var executorService = Executors.newSingleThreadExecutor()) {
final var future = executorService.submit(() -> {
try {
System.out.println("task start");
TimeUnit.SECONDS.sleep(3);
return "abcd";
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.println("task end");
}
});
TimeUnit.SECONDS.sleep(1);
try {
System.out.println("-- get start --");
final var ret = future.get(1, TimeUnit.SECONDS);
System.out.println("-- get end --");
System.out.println("ret = " + ret);
} catch (TimeoutException e) {
System.out.println("TimeoutException!");
}
}
// 結果
// ↓
//task start
//-- get start --
//TimeoutException!
//task end
boolean isCancelled ()
try (final var executorService = Executors.newSingleThreadExecutor()) {
final var future = executorService.submit(() -> {
try {
System.out.println("-- task start --");
TimeUnit.SECONDS.sleep(2);
return "abcd";
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.println("-- task end --");
}
});
TimeUnit.SECONDS.sleep(1);
System.out.println("isCancelled = " + future.isCancelled());
System.out.println("isDone = " + future.isDone());
System.out.println("state = " + future.state());
// タスクが完了するのを待ちます。
System.out.println("get = " + future.get());
System.out.println("isCancelled = " + future.isCancelled());
System.out.println("isDone = " + future.isDone());
System.out.println("state = " + future.state());
// タスク完了後にキャンセルしても isCancelled は true になりません。
System.out.println("----");
System.out.println("cancel = " + future.cancel(false));
System.out.println("isCancelled = " + future.isCancelled());
}
// 結果
// ↓
//-- task start --
//isCancelled = false
//isDone = false
//state = RUNNING
//-- task end --
//isCancelled = false
//isDone = true
//state = SUCCESS
//----
//cancel = false
//isCancelled = false
try (final var executorService = Executors.newSingleThreadExecutor()) {
final var future = executorService.submit(() -> {
try {
System.out.println("-- task start --");
TimeUnit.SECONDS.sleep(2);
return "abcd";
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.println("-- task end --");
}
});
TimeUnit.SECONDS.sleep(1);
System.out.println("isCancelled = " + future.isCancelled());
System.out.println("isDone = " + future.isDone());
System.out.println("state = " + future.state());
System.out.println("----");
System.out.println("cancel = " + future.cancel(false));
System.out.println("isCancelled = " + future.isCancelled());
System.out.println("isDone = " + future.isDone());
System.out.println("state = " + future.state());
}
// 結果
// ↓
//-- task start --
//isCancelled = false
//isDone = false
//state = RUNNING
//----
//cancel = true
//isCancelled = true
//isDone = true
//state = CANCELLED
//-- task end --
try (final var executorService = Executors.newSingleThreadExecutor()) {
final var future = executorService.submit(() -> {
try {
System.out.println("-- task start --");
TimeUnit.SECONDS.sleep(2);
throw new IllegalStateException("Fail!");
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.println("-- task end --");
}
});
TimeUnit.SECONDS.sleep(1);
System.out.println("isCancelled = " + future.isCancelled());
System.out.println("isDone = " + future.isDone());
System.out.println("state = " + future.state());
try {
System.out.println("get = " + future.get());
} catch (ExecutionException e) {
System.out.println("ExecutionException! : " + e.getMessage());
}
System.out.println("isCancelled = " + future.isCancelled());
System.out.println("isDone = " + future.isDone());
System.out.println("state = " + future.state());
}
// 結果
// ↓
//-- task start --
//isCancelled = false
//isDone = false
//state = RUNNING
//-- task end --
//ExecutionException! : java.lang.IllegalStateException: Fail!
//isCancelled = false
//isDone = true
//state = FAILED
boolean isDone ()
このメソッドの使用例は、isCancelled() にまとめて記載しました。
そちらのAPI使用例をご参照ください。
default V resultNow ()
このメソッドの使用例は、exceptionNow() にまとめて記載しました。
そちらのAPI使用例をご参照ください。
default Future.State state ()
このメソッドの使用例は、isCancelled() にまとめて記載しました。
そちらのAPI使用例をご参照ください。
関連記事
- API 使用例
- BlockingQueue (ブロッキング・キュー)
- Callable
- CancellationException
- ConcurrentHashMap.KeySetView (並列処理用セット)
- ConcurrentLinkedDeque (並列処理用・両端キュー)
- ConcurrentLinkedQueue (並列処理用キュー)
- ConcurrentMap (並列処理用マップ)
- ConcurrentModificationException (並列処理例外)
- ConcurrentSkipListSet (並列処理用セット)
- Condition (同期)
- CopyOnWriteArrayList (並列処理用リスト)
- CopyOnWriteArraySet (並列処理用セット)
- CountDownLatch (同期)
- CyclicBarrier (同期)
- Exchanger (同期)
- Executor
- ExecutorService
- Executors
- Future.State
- FutureTask
- InterruptedException (割込み例外)
- Lock (同期)
- Object (オブジェクト)
- Runnable
- Semaphore (セマフォ)
- Thread (スレッド)
- ThreadGroup
- ThreadLocal
- TimeUnit