問題タブ [completion-service]
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 - ExecutorService よりも CompletionService を使用する必要があるのはいつですか?
このブログ投稿で CompletionService を見つけました。ただし、これは、標準の ExecutorService に対する CompletionService の利点を実際に示しているわけではありません。どちらでも同じコードを書くことができます。では、いつ CompletionService が役立つのでしょうか?
明確にするために短いコードサンプルを提供できますか? たとえば、このコード サンプルは、CompletionService が不要な場所を示しているだけです (= ExecutorService と同等)。
java - ExecutorService、CompletionService、BlockingQueue、およびObserverを正しく使用しているJava?
ですから、私はマルチスレッドにかなり慣れておらず、最近すべてのプログラムでこのアイデアを使用しています。さらに使用を開始する前に、Executor、CompletionService、BlockingQueue、およびObserverを使用してマルチスレッドを実装するための正しい効率的な方法であることを確認したいと思います。以下にサンプルコードを提供しますが、最初にそれがどのように機能すると思うかを簡単に説明します。おそらくそれが役立つでしょう。
私が最初に持っているのはBlockingQueueで、すべてのタスクがadd(Task task)メソッドを介してこのキューに追加されます。クラスの作成時に、runメソッドがwhile(true)呼び出しで呼び出され、タスクキューに何かが追加されるまで、キューのブロックが行われます。
run()内のキューに何かが追加されると、queue.take()はキューのアイテムを返します。次に、そのアイテムを取得して、それを処理するWorkerThreadクラスに渡します。そのworkerThreadは、スレッドの終了の待機を処理するCompletionServiceプールに追加されます。
さて、正しいかどうかわからない部分が来ました。runnableを実装し、クラスが初期化されたときに開始される内部クラスもあります。その仕事は、pool.take()を呼び出して永久ループすることです。したがって、これは基本的に、WorkerThreadsの1つが完了するのを待ちます。完了サービスにこれを処理させます。take()が値を取得すると、内部クラスはその値をnotifyobserverメソッドに渡します。
これは大丈夫ですか?タスクキューでwhile(true)ループで実行されるメインクラスと、WorkerThreadから結果を受信するためにプールで待機している内部クラスもループしているのは少し心配です。
これが実装例です。あなたが思うこと?
java - FixedThreadPool および ExecutorCompletionService での OutOfMemory エラー
私は、dbからユーザーのリストを取得し、ディレクトリ(ldapまたはAD)から詳細を更新する必要があるアプリに取り組んでいます。マルチコアマシンでこの手順を実行するため、このアプリを作成しました(以下のコード)。CompletionService を使用して、Future オブジェクトで結果を取得しています。
しばらくすると、「新しいネイティブ スレッドを作成できません」というメッセージでメモリ不足エラーが発生します。タスクマネージャーで、アプリが大量のスレッドを作成したことがわかりますが、サイズがプロセッサの量に等しい固定スレッドプールを作成するように依頼しました。
コードの何が問題になっていますか?
エラー CheckGroupMembership:85 - java.lang.OutOfMemoryError: 新しいネイティブ スレッドを作成できません java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: java.util.concurrent.FutureTask$Sync.innerGet で新しいネイティブ スレッドを作成できません( FutureTask.java:222) で java.util.concurrent.FutureTask.get(FutureTask.java:83)
GetuserDLs タスク
java - Javaでは、複数のプロデューサー/コンシューマーがいつ完了したかを識別できません
複数のプロデューサーコンシューマーパターンプロデューサー1->コンシューマー1/プロデューサー2->コンシューマー2/プロデューサー3を使用します。各プロデューサーは完了サービスを使用しますが、終了時にロジックをコーディングする際に問題が発生します。
問題は、mainがプロデューサー1のキューにいくつかの(x)タスクを配置することです。これにより、プロデューサー1はプロデューサー2に(y)タスクを配置し、プロデューサー2はプロデューサー3にzタスクを配置します。x、y、zは異なるため、mainはzを認識していないため、プロデューサー3の完了キューを調べてz先物を取得することはできません。
そこで、3に初期化されたCountDownLatchと一緒にポイズンピルのアイデアを試しました。メインは、プロデューサー1にはx個のタスクしかないことを知っているので、最後にポイズンピルを送信できます。その後、プロデューサー1がこれを受け取ると、ラッチを減らしてポイズンを送信できます。プロデューサー2にピルを受け取り、プロデューサー2はラッチをデクリメントします。プロデューサー3に送信します。プロデューサー3がそれを受け取ると、ラッチをデクリメントします。mainはcountdownlatch.await()を実行するだけで、すべてのタスクが完了するまで続行できません。ただし、これは、各エグゼキュータサービスが1つのスレッドに制限されている場合にのみ機能します。これは、プロデューサーがポイズンピルを受け取ったときに、先行するすべてのタスクが開始され、完了していないことを意味するだけだからです。
それで、どうすればこれを回避できますか、私はどこかでより簡単な解決策を見逃しているに違いないと思います。
java - Java - ポーリングせずに JPanel で選択したオプションを取得する
と非常によく似た方法で別の JPanel をインスタンス化する JPanel がありますJOptionPane.showMessageDialog(...)
。ただし、サイズ、メッセージ、ボタンの位置などを変更したいので、このオプションは使用しません。ただし、最終的なユーティリティは同じである必要があり、選択されたオプションが選択されるとすぐに返されます。actionPerformed(...)
問題は、メソッドから変更されるまで null に初期化される可能性のある属性をポーリングする必要がないことです。代わりに、どういうわけか a を使用するCompletionService
ことを考えていましたが、それを正確に行う方法を考えることができません。どのように定義すればよいでしょうか?Future
メソッドで選択する必要があると思いますが、getSelectedOption()
メソッドで生成する必要があります actionPerformed(...)
。これを行う方法?
java - 他のすべてのスレッドをただちに停止する Java マルチスレッド
私はこのコードを持っています:
メインクラス:
出力: ...
1 つのスレッドがパスワードを検出し、stopped を true に設定した場合、別のスレッドはすぐには停止しません。なんで?
java - CompletionService で大量のタスクを処理する
マルチコア マシンで多数の (1 億を超える) 要求を処理する必要があります (各要求はデータ ファイル内の行を処理するためのものであり、リモート システムとの I/O を伴います。詳細はあまり重要ではありませんが、 、特定のタスクは、いくつかのデータ ファイルから配布された Hazelcast マップを読み込むことです)。実行はThreadPoolExecutorを通じて処理されます。1 つのスレッドがファイルを読み取り、データを複数の独立したスレッドに送信してマップに配置します。マシンには 32 個のコアがあるため、マップの並列読み込みに十分な空き容量があります。
リクエストの数が多いため、タスクを作成して executor サービスのキューに入れるという一般的な方法は、キューに入れられたタスクが大量のメモリを消費するため、現実的ではありません。
ExecutorCompletionServiceをもたらします。それを使用すると、前の操作が完了したときにタスクが送信されます。これは、呼び出しtake()
(またはpoll()
、該当する場合) によって認識されます。これは、executor サービスのすべてのスレッドが使用されている場合に正常に機能します。ただし、「すべてのスレッドをロードする」ことはまだ行われていません。次の 2 つのフェーズがあります。
キューをいっぱいにする: プールにまだ未使用のスレッドがある間に、タスクを ExecutorCompletionService に送信し、さらに送信するまで待機しません。
feed the queue : スレッドがすべて使用されたら、前のタスクが終了したときにのみタスクを送信します。したがって、行は可能な限り迅速にフィードされますが、それ以上速くはならず、キューにも入れられません。
上記はコーディングできますが、上記のロジックが既に実装されているかどうか疑問に思っていて、どういうわけか見逃していました。よくあるシナリオだと思うので質問します。