6

Java のFutureTaskFutureRunnableCallableおよびExecutorService型を操作しようとしています。

これらのビルディング ブロックを構成するためのベスト プラクティスは何ですか?

複数FutureTaskの があり、それらを順番に実行したいとします。

もちろん、各サブタスクの結果を順番に送信/待機する別の FutureTask を作成することもできますが、呼び出しのブロックは避けたいです。

別のオプションは、これらのサブタスクが完了したときにコールバックを呼び出し、コールバックで次のタスクをスケジュールすることです。しかし、そのルートに進むと、ボイラープレートをあまり作成せずに、サブタスクの例外も処理する適切な外部 FutureTask オブジェクトを作成するにはどうすればよいでしょうか?

ここで何かが恋しいですか?

4

3 に答える 3

4

通常、チュートリアルでは説明されていませんが、非常に重要なこと:

Runnables to be executed on an ExecutorService should not block. これは、ブロックするたびに作業スレッドがオフになり、ExecutorService の作業スレッドの数が制限されている場合はデッドロック (スレッド スターベーション) に陥るリスクがあり、ExecutorService の作業スレッドの数が無制限の場合は、メモリが不足しています。タスクでのブロック操作は ExecutorService のすべての利点を単純に破壊するため、ブロック操作は通常のスレッドでのみ使用してください。

FutureTask.get()ブロック操作であるため、ExecutorService タスクからではなく、通常のスレッドで使用できます。つまり、ビルディングブロックとして機能することはできず、実行結果をマスタースレッドに配信するだけです。

タスクから実行を構築するための正しいアプローチは、次のタスクのすべての入力データの準備が整ったときに次のタスクを開始することです。これにより、タスクは入力データの待機をブロックする必要がなくなります。したがって、中間結果を保存し、すべての引数が到着したときに新しいタスクを開始する一種のゲートが必要です。したがって、タスクは他のタスクを明示的に開始する必要はありません。したがって、引数の入力ソケットとそれらを計算する Runnable で構成されるゲートは、ExcutorServices での計算の適切なビルディング ブロックと見なすことができます。

このアプローチは、データフローまたはワークフローと呼ばれます (ゲートを動的に作成できない場合)。

Akka のようなアクター フレームワークはこのアプローチを使用しますが、アクターが単一の入力ソケットを持つゲートであるという点で制限があります。

https://github.com/rfqu/df4jで公開されている真のデータフロー ライブラリを作成しました。

于 2013-02-05T12:36:12.913 に答える
0

ユーザーに表示される前に遅延を引き起こそうとして、ScheduledFutureで同様のことをしようとしました。これが私が思いついたものです。すべての「遅延」に同じScheduledFutureを使用するだけです。コードは次のとおりです。

    public static final ScheduledExecutorService scheduler = Executors
        .newScheduledThreadPool(1);
    public ScheduledFuture delay = null;

    delay = scheduler.schedule(new Runnable() {
    @Override
    public void run() {
    //do something
    }
    }, 1000, TimeUnit.MILLISECONDS);

    delay = scheduler.schedule(new Runnable() {
    @Override
    public void run() {
    //do something else
    }
    }, 2000, TimeUnit.MILLISECONDS);

これがアンディに役立つことを願っています

于 2013-02-05T10:14:23.360 に答える
0

通常のアプローチは次のとおりです。

  • ExecutorService (タイプ、スレッド数) について決定します。
  • タスク キューについて決定します (ノンブロッキングの期間)。

タスクの結果を待つ外部コードがある場合: * タスクを Callable として送信します (キューを使い切らない限り、これはブロックされません)。* 未来に電話してください。

タスクの終了後にいくつかのアクションを自動的に実行したい場合:

  • Callable または Runnable として送信できます。
  • タスク内の最後のコードとして、最後に行う必要があることを追加するだけです。Activity.runOnUIThread を使用して、これらの最終アクションで GUI を変更する必要があります。

通常、タスクを送信するためだけに、別のタスクを送信したり、コールバックをスケジュールしたりできる時期を積極的にチェックするべきではありません。スレッド キュー (必要に応じてブロック) がこれを処理します。

于 2013-02-05T10:16:59.023 に答える