問題タブ [executorservice]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - JavaのFutureとFutureTaskの違いは何ですか?
タスクを使用してを返すExecutorService
ことができるのでsubmit
、タスクをラップしてメソッドを使用する必要があるのはなぜですか? どちらも同じことをしていると感じます。Callable
Future
FutureTask
Callable
execute
java - Java ExecutorService: 再帰的に作成されたすべてのタスクの awaitTermination
を使用しExecutorService
てタスクを実行します。このタスクは、同じタスクにサブミットされる他のタスクを再帰的に作成できExecutorService
、それらの子タスクもそれを実行できます。
すべてのタスクが完了する (つまり、すべてのタスクが完了し、新しいタスクが送信されない) まで待ちたいという問題があります。
ExecutorService.shutdown()
新しいタスクが によって受け入れられなくなるため、メイン スレッドで呼び出すことができませんExecutorService
。
Callingは、呼び出されてExecutorService.awaitTermination()
いない場合は何もしないようです。shutdown
だから私はここで立ち往生しています。ExecutorService
すべてのワーカーがアイドル状態であることを確認するのはそれほど難しいことではありませんね。私が思いつくことができる唯一の洗練されていない解決策は、 a を直接使用してThreadPoolExecutor
、時々クエリを実行することgetPoolSize()
です。それを行うより良い方法は本当にありませんか?
java - スレッドセーフな CompletionService に相当するものを実装または見つけるにはどうすればよいですか?
本質的にマルチスレッドである Tomcat コンテナー内で実行されている単純な Web サービスがあります。サービスに送られる各リクエストで、外部サービスへの同時呼び出しを行いたいと考えています。java.util.concurrent の ExecutorCompletionService は、私を部分的にそこに連れて行きます。スレッド プールを提供すると、同時呼び出しの実行が処理され、結果の準備ができたときに通知されます。
特定の受信リクエストを処理するコードは次のようになります。
これはうまく機能するはずですが、着信要求ごとに新しいスレッド プールが割り当てられるため、非常に非効率的です。CompletionService を共有インスタンスとして移動すると、同じ CompletionService とスレッド プールを共有する複数のリクエストでスレッド セーフの問題が発生します。リクエストがタスクを送信して結果を取得すると、取得する結果は送信したものとは異なります。
したがって、私が必要としているのは、スレッドセーフな CompletionService です。これにより、すべての着信要求で共通のスレッド プールを共有できます。各スレッドがタスクを完了すると、着信要求に適したスレッドに通知して、結果を収集できるようにする必要があります。
この種の機能を実装する最も簡単な方法は何ですか? このパターンは何度も適用されてきたと思います。これが Java 同時実行ライブラリによって提供されるものなのか、Java 同時実行ビルディング ブロックの一部を使用して簡単に構築できるのかはわかりません。
更新:忘れていた 1 つの警告は、提出したタスクが完了したらすぐに通知を受け取りたいということです。これは、タスクと結果の生成と消費を分離するため、CompletionService を使用する主な利点です。結果が返される順序は実際には気にしません。結果が順番に返されるのを待っている間、不必要にブロックすることは避けたいと思います。
java - 軽量で折りたたみ可能なExecutorの実装?
Android用のモバイルアプリを作成していますが、リストアダプターごとにHTTPリクエストをプールする必要があります。基本的にExecutorService
「崩壊」する実装が必要です。つまり、最大n個のスレッドを使用しますが、スレッドが完了するとすぐに期限切れになり、非常に軽量になります。需要が高い場合は、タスクをキューにダンプして、スレッドが使用可能になるのを待ちます。自分で書くことなくこれを行う方法はありExecutorService
ますか、それとも手を汚してそれを行うべきですか?
java - タイマーを使用した Java スレッドのスケジューリング
最後に実行してから一定の間隔で実行する必要がある Runnable クラスがあります。例: ProcessThread は、終了後 2 分ごとに実行されます。したがって、ProcessThread を 1:00 に開始して 5 分 (1:05 に終了) すると、次に実行されるのは 1:07 になります。その実行に 3 分かかる場合 (1:10 に終了)、次の実行は 1:12 に開始されます) など。
2 分の固定レートで設定することはできません。2 番目のスレッドが起動され、最初のスレッドがまだ終了していないためです。
だから、これが私の現在のコードですが、私が持っている方法では、スレッドを作成し続け、それらを終了することはありません...したがって、最終的に私のメモリはどんどん増えていきます:
主要:
ExecuteThread (try-catch を取り出しました):
MyProcessThread 内でスケジューラを実行する前に、結果は同じでした。これは正しい方向に見えますが、まだ何かが間違っています。
java - 実行するタスクのツリーで ExecutorService を使用する
少し問題がありました。:)
常に N スレッドのみがバックグラウンド タスクを実行するようにしたいと考えています。これを行うために、固定スレッド プール エグゼキュータを使用しました。うまく機能しているように見えました。
その後、問題が見つかりました。エグゼキューターを使用していくつかの並列作業を行うクラスがあり、エグゼキューター スレッド内で別のクラスを呼び出し、そのスレッドも並列作業を行い、それを待機しようとしているとします。何が起こるかは次のとおりです。
- メイン スレッドは、第 1 レベルのメソッドを呼び出します。
- このメソッドは、16 のタスクに並列化できると考え、作業を分割します。
- 16 個のタスクがエグゼキューターにサブミットされます。
- メイン スレッドは、そのタスクが完了するのを待機し始めます。
- 利用可能なスレッドが 4 つあるとすると、最初の 4 つのタスクがそれぞれ選択されて実行されます。したがって、キューには 12 個のタスクが残っています。
- ここで、これらのタスクの 1 つが他のメソッドを呼び出します。
- この新しい方法は、2 つのタスクに並列化できると考えています。それが並列マージソートの最初のステップであるか、それらの線に沿った何かであるとしましょう。
- 2 つのタスクがエグゼキューターにサブミットされます。
- このスレッドは、タスクが完了するのを待ち始めます。
ええとああ。そのため、この時点で、4 つのスレッドすべてがタスクの完了を待機していますが、これらのタスクを実際に実行しているエグゼキュータを共同でブロックしています。
この問題の解決策 1 は次のとおりです。エグゼキューターに新しいタスクを送信するときに、すべてのスレッドを既に実行しており、エグゼキューター スレッドの 1 つで既に実行している場合は、タスクをインラインで実行します。これは 10 か月間問題なく機能していましたが、現在問題が発生しています。サブミットしている新しいタスクがまだ比較的大きい場合、メソッドが他のタスクをキューに追加することを新しいタスクがブロックする状況に陥る可能性があります。そうしないと、他のワーカー スレッドによって取得される可能性があります。そのため、スレッドが作業をインラインで処理している間、かなりの遅延が発生します。
バックグラウンド タスクの潜在的に無限のツリーを実行するという中心的な問題に対するより良い解決策はありますか? executor サービスに相当する .NET には、キューから盗む何らかの組み込み機能があり、元のデッドロックの問題が発生するのを防ぎます。これは、私が知る限り、理想的なソリューションです。しかし、Java の土地ではどうでしょうか。
java - CompletionServiceを使用して時間がかかりすぎるタスクをキャンセルするにはどうすればよいですか?
2スレッドのFixedThreadPoolExecutorServiceにラップされたCompletionServiceを使用して、いくつかのFutureタスクを送信し、送信されたタスクの数に等しいループを設定してセットアップし、completionservice.take()を使用してすべてが完了するか失敗するのを待ちます。問題は非常にまれに終了しないことがあるので(理由はわかりません)、take()メソッドをpoll(300、Timeout.SECONDS)に変更しました。これは、1つのタスクが完了するまでに5分以上かかる場合のアイデアです。ポーリングは失敗し、最終的にはループから抜け出します。すべての先物を調べて、future.cancel(true)を呼び出して、問題のあるタスクを強制的にキャンセルできます。
しかし、コードを実行してハングすると、ポーリングが5分ごとに1回継続して失敗し、それ以上タスクが実行されないことがわかります。そのため、2人のワーカーが何らかの方法でデッドロックし、終了せず、追加のタスクの開始を許可しないと想定します。タイムアウトは5分であり、実行するタスクがまだ1000あるため、ループを解除するのにかかる時間が長すぎたため、ジョブをキャンセルしました。
ですから、私がやりたいのは、5分以内に完了しなかった場合に現在のタスクを中断/強制的にキャンセルすることですが、それを行う方法がわかりません。
このコードサンプルは、Imが話していることの簡略版を示しています
出力
java - ExecutorService 内のスレッドのスリープ (Java/Clojure)
clojure プログラム内で作成されているかなりの数のスレッドがあります。
私にとってはJVMの間でしばらく経ちましたが、エグゼキューターによって実行されている関数内でスリープまたは収量を使用することに反対する議論があるかどうか、基本的にここで疑問に思っていますか? 私が正しく理解していれば、この場合、すべてのワーカーが独自のスレッドを持っているため、副作用はないはずです。
Executor が FixedThreadPool を使用している場合:
スレッドは作業が完了するまでプールに返されないため、状況はさらに複雑になります。つまり、スレッドがスリープ状態の場合、キューに入れられた他のワーカーの完了に時間がかかります。
この場合のスレッド化についての私の理解は正しいですか?
(注:私のデザインは実際には間違っていると思いますが、正しいページにいることを確認したいだけです)
java - Javaは、スレッドの実行が数回成功した後、ループでExecutionExceptionをスローします
呼び出し可能なスレッドに問題があります。
コードスニペットは次のとおりです。
上記のコードは18回正しく実行され、18回目以降にExecutionExceptionをスローします。
私は何が間違っているのですか?
ありがとう!
java - 複数のスレッドを使用してファイル データを構築するときに表示される余分なバイト数
私は大規模なデータセットに取り組んでおり、モデルを構築した後、次のようにマルチスレッド (Java のプロジェクト全体) を使用します。
各 callable から結果を受け取ったら、それをファイルに出力します。これは、最初の Callables のリストが作成された順序どおりに出力されますか? 他の人より先に完了したにもかかわらず?するべきだと思われますが、確かではありません。
また、合計 620 万バイトが出力ファイルに書き込まれると予想しています。しかし、追加の 2000 バイトを取得します (無料です)。それは私の提出を台無しにします、そしてそれはいくつかの並行性の問題によるものだと思います。これを小さなデータセットでテストしたところ、問題なく動作しているようです (264 バイトが期待され、受信されました)。
Executor フレームワークまたは Futures で何か問題がありますか?