Java : FutureTask - API使用例
FutureTask (Java SE 18 & JDK 18) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様のおともにどうぞ。
概要
基本的には Futureインタフェース と同じです。
ただし、いくつかオーバライドすると便利なメソッドが追加されています。
FutureTaskはそれ自体が Runnable でもあるので、ExecutorService に直接 submit できます。
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
System.out.println("task run");
}, "abcd");
executorService.submit(futureTask);
System.out.println("get : " + futureTask.get());
} finally {
executorService.shutdown();
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// 結果
// ↓
//task run
//get : abcd
//term : true
コンストラクタ
FutureTask (Runnable runnable, V result)
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
System.out.println("task run");
}, "abcd");
executorService.submit(futureTask);
System.out.println("get : " + futureTask.get());
} finally {
executorService.shutdown();
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// 結果
// ↓
//task run
//get : abcd
//term : true
FutureTask (Callable<V> callable)
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
System.out.println("task run");
return "abcd";
});
executorService.submit(futureTask);
System.out.println("get : " + futureTask.get());
} finally {
executorService.shutdown();
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// 結果
// ↓
//task run
//get : abcd
//term : true
メソッド
boolean cancel (boolean mayInterruptIfRunning)
// 基準となる時刻
final long current = System.nanoTime();
// 基準となる時刻からの差分を秒として取得
final DoubleSupplier getTime = () -> (System.nanoTime() - current) / 1000000000.0;
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
try {
System.out.println("task start : " + getTime.getAsDouble() + " sec.");
TimeUnit.SECONDS.sleep(2);
return "abcd";
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.println("task end : " + getTime.getAsDouble() + " sec.");
}
});
executorService.submit(futureTask);
TimeUnit.SECONDS.sleep(1);
// mayInterruptIfRunning = false
final var ret = futureTask.cancel(false);
System.out.println("cancel = " + ret + " : " + getTime.getAsDouble() + " sec.");
} finally {
executorService.shutdown();
System.out.println("shutdown : " + getTime.getAsDouble() + " sec.");
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term = " + ret + " : " + getTime.getAsDouble() + " sec.");
// 結果
// ↓
//task start : 0.0030879 sec.
//cancel = true : 1.0165037 sec.
//shutdown : 1.0204428 sec.
//task end : 2.0135346 sec.
//term = true : 2.0140798 sec.
// ※mayInterruptIfRunning = false では割込みは発生しません。
final long current = System.nanoTime();
final DoubleSupplier getTime = () -> (System.nanoTime() - current) / 1000000000.0;
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
try {
System.out.println("task start : " + getTime.getAsDouble() + " sec.");
TimeUnit.SECONDS.sleep(2);
return "abcd";
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.println("task end : " + getTime.getAsDouble() + " sec.");
}
});
executorService.submit(futureTask);
TimeUnit.SECONDS.sleep(1);
// mayInterruptIfRunning = true
final var ret = futureTask.cancel(true);
System.out.println("cancel = " + ret + " : " + getTime.getAsDouble() + " sec.");
} finally {
executorService.shutdown();
System.out.println("shutdown : " + getTime.getAsDouble() + " sec.");
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term = " + ret + " : " + getTime.getAsDouble() + " sec.");
// 結果
// ↓
//task start : 0.0035929 sec.
//Interrupted!
//task end : 1.0059904 sec.
//cancel = true : 1.005947 sec.
//shutdown : 1.0097252 sec.
//term = true : 1.0098963 sec.
// ※mayInterruptIfRunning = true は割込みを発生させます。
final long current = System.nanoTime();
final DoubleSupplier getTime = () -> (System.nanoTime() - current) / 1000000000.0;
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
try {
System.out.println("task start : " + getTime.getAsDouble() + " sec.");
TimeUnit.SECONDS.sleep(2);
return "abcd";
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.println("task end : " + getTime.getAsDouble() + " sec.");
}
});
executorService.submit(futureTask);
// タスクが完了するのを待ちます。
TimeUnit.SECONDS.sleep(3);
final var ret = futureTask.cancel(true);
System.out.println("cancel = " + ret + " : " + getTime.getAsDouble() + " sec.");
} finally {
executorService.shutdown();
System.out.println("shutdown : " + getTime.getAsDouble() + " sec.");
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term = " + ret + " : " + getTime.getAsDouble() + " sec.");
// 結果
// ↓
//task start : 0.0022581 sec.
//task end : 2.0066302 sec.
//cancel = false : 3.0161829 sec.
//shutdown : 3.0202056 sec.
//term = true : 3.0203844 sec.
// ※すでに終了しているタスクに対してcancelするとfalseを返します。
protected void done ()
※API仕様には明記されていませんが、正常に完了したときとcancelされたときで、doneが実行されるスレッドが変わるようです。ご注意ください。
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
try {
System.out.println("-- task start --");
System.out.println("task thread id : " + Thread.currentThread().getId());
TimeUnit.SECONDS.sleep(1);
return "abcd";
} finally {
System.out.println("-- task end --");
}
}) {
@Override
protected void done() {
System.out.println("done!");
System.out.println("done thread id : " + Thread.currentThread().getId());
}
};
System.out.println("main thread id : " + Thread.currentThread().getId());
executorService.submit(futureTask);
System.out.println("get : " + futureTask.get());
} finally {
executorService.shutdown();
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// 結果
// ↓
//main thread id : 1
//-- task start --
//task thread id : 19
//-- task end --
//done!
//get : abcd
//done thread id : 19
//term : true
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
try {
System.out.println("-- task start --");
System.out.println("task thread id : " + Thread.currentThread().getId());
TimeUnit.SECONDS.sleep(2);
return "abcd";
} finally {
System.out.println("-- task end --");
}
}) {
@Override
protected void done() {
System.out.println("done!");
System.out.println("done thread id : " + Thread.currentThread().getId());
}
};
System.out.println("main thread id : " + Thread.currentThread().getId());
executorService.submit(futureTask);
TimeUnit.SECONDS.sleep(1);
futureTask.cancel(true);
System.out.println("isCancelled : " + futureTask.isCancelled());
} finally {
executorService.shutdown();
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// 結果
// ↓
//main thread id : 1
//-- task start --
//task thread id : 19
//-- task end --
//done!
//done thread id : 1
//isCancelled : true
//term : true
V get ()
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
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");
}
});
executorService.submit(futureTask);
TimeUnit.SECONDS.sleep(1);
System.out.println("-- get start --");
final var ret = futureTask.get();
System.out.println("-- get end --");
System.out.println("future ret : " + ret);
} finally {
executorService.shutdown();
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// 結果
// ↓
//task start
//-- get start --
//task end
//-- get end --
//future ret : abcd
//term : true
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
try {
System.out.println("task start");
TimeUnit.SECONDS.sleep(2);
throw new IllegalStateException("Exception!");
} catch (InterruptedException e) {
System.out.println("Interrupted!");
return null;
} finally {
System.out.println("task end");
}
});
executorService.submit(futureTask);
TimeUnit.SECONDS.sleep(1);
System.out.println("-- get start --");
final var ret = futureTask.get();
System.out.println("-- get end --");
System.out.println("future ret : " + ret);
} catch (ExecutionException e) {
System.out.println("ExecutionException! : " + e.getMessage());
} finally {
executorService.shutdown();
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// 結果
// ↓
//task start
//-- get start --
//task end
//ExecutionException! : java.lang.IllegalStateException: Exception!
//term : true
final var executorService = Executors.newScheduledThreadPool(2);
try {
final var futureTask = new FutureTask<>(() -> {
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");
}
});
executorService.submit(futureTask);
// 2秒後にキャンセルします。
executorService.schedule(() -> {
System.out.println("future cancel");
futureTask.cancel(true);
}, 2, TimeUnit.SECONDS);
TimeUnit.SECONDS.sleep(1);
System.out.println("-- get start --");
final var ret = futureTask.get();
System.out.println("-- get end --");
System.out.println("future ret : " + ret);
} catch (CancellationException e) {
System.out.println("CancellationException!");
} finally {
executorService.shutdown();
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// 結果
// ↓
//task start
//-- get start --
//future cancel
//Interrupted!
//task end
//CancellationException!
//term : true
V get (long timeout, TimeUnit unit)
get() の使用例もあわせてご参照ください。
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
try {
System.out.println("task start");
TimeUnit.SECONDS.sleep(3);
return "abcd";
} finally {
System.out.println("task end");
}
});
executorService.submit(futureTask);
TimeUnit.SECONDS.sleep(1);
System.out.println("-- get start --");
final var ret = futureTask.get(5, TimeUnit.SECONDS);
System.out.println("-- get end --");
System.out.println("future ret : " + ret);
} catch (TimeoutException e) {
System.out.println("TimeoutException!");
} finally {
executorService.shutdown();
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// 結果
// ↓
//task start
//-- get start --
//task end
//-- get end --
//future ret : abcd
//term : true
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
try {
System.out.println("task start");
TimeUnit.SECONDS.sleep(3);
return "abcd";
} finally {
System.out.println("task end");
}
});
executorService.submit(futureTask);
TimeUnit.SECONDS.sleep(1);
System.out.println("-- get start --");
final var ret = futureTask.get(1, TimeUnit.SECONDS);
// ↓ここは呼び出されません。
System.out.println("-- get end --");
System.out.println("future ret : " + ret);
} catch (TimeoutException e) {
System.out.println("TimeoutException!");
} finally {
executorService.shutdown();
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// 結果
// ↓
//task start
//-- get start --
//TimeoutException!
//task end
//term : true
boolean isCancelled ()
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
try {
System.out.println("task start");
TimeUnit.SECONDS.sleep(2);
return "abcd";
} finally {
System.out.println("task end");
}
});
executorService.submit(futureTask);
TimeUnit.SECONDS.sleep(1);
System.out.println("-- before cancel -- : " + futureTask.isCancelled());
futureTask.cancel(false);
System.out.println("-- after cancel -- : " + futureTask.isCancelled());
} finally {
executorService.shutdown();
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// 結果
// ↓
//task start
//-- before cancel -- : false
//-- after cancel -- : true
//task end
//term : true
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
try {
System.out.println("task start");
TimeUnit.SECONDS.sleep(2);
return "abcd";
} finally {
System.out.println("task end");
}
});
executorService.submit(futureTask);
TimeUnit.SECONDS.sleep(1);
System.out.println("-- before cancel -- : " + futureTask.isCancelled());
// タスクが完了するのを待ちます。
TimeUnit.SECONDS.sleep(2);
futureTask.cancel(false);
// タスクの完了後にキャンセルをしても、isCancelledはtrueになりません。
System.out.println("-- after cancel -- : " + futureTask.isCancelled());
} finally {
executorService.shutdown();
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// 結果
// ↓
//task start
//-- before cancel -- : false
//task end
//-- after cancel -- : false
//term : true
boolean isDone ()
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
try {
System.out.println("task start");
TimeUnit.SECONDS.sleep(2);
return "abcd";
} finally {
System.out.println("task end");
}
});
executorService.submit(futureTask);
TimeUnit.SECONDS.sleep(1);
System.out.println("-- isDone 1 -- : " + futureTask.isDone());
// タスクが完了するのを待ちます。
TimeUnit.SECONDS.sleep(2);
System.out.println("-- isDone 2 -- : " + futureTask.isDone());
} finally {
executorService.shutdown();
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// 結果
// ↓
//task start
//-- isDone 1 -- : false
//task end
//-- isDone 2 -- : true
//term : true
final var executorService = Executors.newSingleThreadExecutor();
try {
final var futureTask = new FutureTask<>(() -> {
try {
System.out.println("task start");
TimeUnit.SECONDS.sleep(2);
return "abcd";
} finally {
System.out.println("task end");
}
});
executorService.submit(futureTask);
TimeUnit.SECONDS.sleep(1);
System.out.println("-- isDone 1 -- : " + futureTask.isDone());
futureTask.cancel(false);
// タスクが終了していなくても、キャンセルされた直後にDoneとなります。
System.out.println("-- isDone 2 -- : " + futureTask.isDone());
} finally {
executorService.shutdown();
}
final var ret = executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// 結果
// ↓
//task start
//-- isDone 1 -- : false
//-- isDone 2 -- : true
//task end
//term : true
void run ()
final var futureTask = new FutureTask<>(() -> {
System.out.println("Run!");
return "abcd";
});
// ExecutorServiceを使わずに直接実行します。
futureTask.run();
System.out.println("isDone : " + futureTask.isDone());
final var ret = futureTask.get();
System.out.println("get ret : " + ret);
// 結果
// ↓
//Run!
//isDone : true
//get ret : abcd
protected boolean runAndReset ()
final var runnable = new Runnable() {
private int count;
@Override
public void run() {
count++;
System.out.println("count : " + count);
}
};
final var task = new FutureTask<>(runnable, "abcd") {
@Override
public void run() {
final var ret = runAndReset();
System.out.println("runAndReset ret : " + ret);
}
};
task.run();
System.out.println("isDone : " + task.isDone());
task.run();
System.out.println("isDone : " + task.isDone());
task.run();
System.out.println("isDone : " + task.isDone());
// 結果
// ↓
//count : 1
//runAndReset ret : true
//isDone : false
//count : 2
//runAndReset ret : true
//isDone : false
//count : 3
//runAndReset ret : true
//isDone : false
final var task = new FutureTask<>(() -> {
throw new IllegalStateException("Exception!");
}) {
@Override
public void run() {
final var ret = runAndReset();
System.out.println("runAndReset ret : " + ret);
}
};
task.run();
System.out.println("isDone : " + task.isDone());
// 結果
// ↓
//runAndReset ret : false
//isDone : true
protected void set (V v)
final var futureTask = new FutureTask<>(() -> {
try {
System.out.println("task start");
return "abcd";
} finally {
System.out.println("task end");
}
}) {
@Override
protected void set(String s) {
super.set(s);
System.out.println("set : " + s);
}
};
futureTask.run();
System.out.println("isDone : " + futureTask.isDone());
// 結果
// ↓
//task start
//task end
//set : abcd
//isDone : true
protected void setException (Throwable t)
final var futureTask = new FutureTask<>(() -> {
try {
System.out.println("task start");
throw new IllegalStateException("Exception!");
} finally {
System.out.println("task end");
}
}) {
@Override
protected void setException(Throwable t) {
super.setException(t);
System.out.println("setException : " + t);
}
};
futureTask.run();
System.out.println("isDone : " + futureTask.isDone());
// 結果
// ↓
//task start
//task end
//setException : java.lang.IllegalStateException: Exception!
//isDone : true
String toString ()
final var futureTask = new FutureTask<>(() -> "abcd");
final var ret1 = futureTask.toString();
System.out.println("before run : " + ret1);
futureTask.run();
final var ret2 = futureTask.toString();
System.out.println("after run : " + ret2);
// 結果
// ↓
//before run : java.util.concurrent.FutureTask@c05fddc[Not completed, task = ...]
//after run : java.util.concurrent.FutureTask@c05fddc[Completed normally]
関連記事
- API 使用例
- BlockingQueue (ブロッキング・キュー)
- Callable
- CancellationException
- ConcurrentHashMap.KeySetView (並列処理用セット)
- ConcurrentLinkedDeque (並列処理用・両端キュー)
- ConcurrentLinkedQueue (並列処理用キュー)
- ConcurrentMap (並列処理用マップ)
- ConcurrentModificationException (並列処理例外)
- ConcurrentSkipListSet (並列処理用セット)
- Condition (同期)
- CopyOnWriteArrayList (並列処理用リスト)
- CopyOnWriteArraySet (並列処理用セット)
- CountDownLatch (同期)
- CyclicBarrier (同期)
- Exchanger (同期)
- Executor
- ExecutorService
- Executors
- Future
- Future.State
- InterruptedException (割込み例外)
- Lock (同期)
- Object (オブジェクト)
- Runnable
- Semaphore (セマフォ)
- Thread (スレッド)
- ThreadGroup
- ThreadLocal
- TimeUnit