Java Future Multithreadingはどのように結果を返しますか?
-
27-09-2019 - |
質問
私はまだJavaでFutureとCallableの使用について学んでいます。この質問につまずく:
私がクラスを持っていると言ってください:
TaskWorker implements Callable {
public String id;
public TaskWorker(String id) {
this.id = id;
}
public Documents call() trows Exception {
//Assume here, that Search and Doc are my own method to search and retrieve docs
Search search = new Search();
Documents docResult = search.process(id);
//think about documents has getDocs
//docResult.getDocs() will return number of document found from search
return docResult;
}
}
そして、これが主な方法です:
public static void main(String[] args) {
//assume here, that I build in request contains many Id
Request request = new Request();
request.process;
ExecutorService service = Executors.newFixedThreadPool(3);
List<Future<Documents>> result = new ArrayList<Future<Documents>>();
for (int i=0;i<request.length;i++) {
Callable<Documents> worker = new TaskWorker(request.getId[i]);
Future<Documents> submit = executor.submit(worker);
result.add(submit);
}
Response response = new Response();
ArrayList<Documents> docList = new ArrayList<Documents>();
for (Future<Documents> future:result) {
docList.add(future.get().getDocs());
}
response.setDocuments(docList);
}
私がやろうとしているのは、リクエストIDのそれぞれが個別の検索プロセスであるため、個別のスレッドで実行するリクエストの一部を破ることです。そのため、結果を将来のオブジェクトに保存することにより、Javaプーリングを利用しようとしています。
私が混乱しているのは、この場合、未来はどのように機能するかということです。スレッドの完了ごとに、結果は保持されますか?そして、すべてのプロセスが終了した後、私は将来のオブジェクトをループして結果を正しく取得することができますか?
また、プロセスが順番に実行されるという保証はありません(1,2,3,4など)?その場合、各元のリクエストを将来の結果に関連付けたい場合、最良の戦略は何ですか?
お知らせ下さい。
ありがとう
解決
また、プロセスが順番に実行されるという保証はありません(1,2,3,4など)?その場合、各元のリクエストを将来の結果に関連付けたい場合、最良の戦略は何ですか?
バックグラウンドスレッドが開始および終了される順序を知ることはできませんが、結果アレイリストをループすると、もちろん、それらを提出した順序で結果が得られます。ここで起こる可能性のある唯一のことは、.get()が、この将来のオブジェクトの特定の結果が利用可能になるまでブロックすることです。
他のヒント
SynchronizedMapを作成し、リクエストとともにコンストラクターのタスクワーカーに渡す必要があります。タスクワーカーは、ジョブを終了するときにリクエストを追加してマップに結果を追加する必要があります。
結果を得るために先物をループする必要はありません。すべてのジョブが終了していることを確認してください。