web-dev-qa-db-ja.com

完了できるものをスケジュールすることは可能ですか?

JavaでCompletableFutureをスケジュールする方法はありますか?私がやりたいことは、いくつかの遅延で実行されるタスクをスケジュールし、それが完了したときに非同期的に実行されるべき他の操作と連鎖することです。これまでにこれを行う方法はありませんでした。

良いOL '先物のために私たちはe.gを持っています。 ScheduleDexeCutorServiceは、このような遅延で実行されるタスクをスケジュールすることができます。

ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
Future<String> future = scheduledExecutorService.schedule(() -> "someValue", 10, TimeUnit.SECONDS);
 _

完成可能なものには同様の方法がありますか?

9
Łukasz Gruba

言ったように 、Java 9ではサポートがあります。

しかし、Java 8の下に同様の機能を作成するのは難しくありません。あなたはすでに必要な要素と名付けられました:

// prefer this constructor with zero core threads for a shared pool,
// to avoid blocking JVM exit
static final ScheduledExecutorService SCHEDULER = new ScheduledThreadPoolExecutor(0);
static Executor delayedExecutor(long delay, TimeUnit unit)
{
  return delayedExecutor(delay, unit, ForkJoinPool.commonPool());
}
static Executor delayedExecutor(long delay, TimeUnit unit, Executor executor)
{
  return r -> SCHEDULER.schedule(() -> executor.execute(r), delay, unit);
}
 _

これはJava 9機能と同様に使用できます。

Executor afterTenSecs = delayedExecutor(10L, TimeUnit.SECONDS);
CompletableFuture<String> future 
  = CompletableFuture.supplyAsync(() -> "someValue", afterTenSecs);

future.thenAccept(System.out::println).join();
 _

共有スケジュールされたエグゼキュレスのスレッドがJVMが終了しないようにするには、注意を払う必要があります。コアプールサイズのゼロの代替手段は、デーモンスレッドを使用することです。

static final ScheduledExecutorService SCHEDULER
  = Executors.newSingleThreadScheduledExecutor(r -> {
    Thread t = new Thread(r);
    t.setDaemon(true);
    return t;
  });
 _
3
Holger

Java 9以降を使用している場合は、 CompletableFuture#delayedExecutor(long,TimeUnit) /のニーズに合うことがあります。

指定された遅延の後にタスクをデフォルトのexecutorに送信する新しいexecutor(または非正の場合は遅延がない)を返します。各遅延は、返されたexecutorのexecuteメソッドの呼び出し時に始まります。

_Executor delayed = CompletableFuture.delayedExecutor(10L, TimeUnit.SECONDS);
CompletableFuture.supplyAsync(() -> "someValue", delayed)
    .thenAccept(System.out::println)
    .join();
_

オーバーロード /ここで、「デフォルトの実行因子」の代わりに使用するExecutorを指定できます。

3
Slaw