1

ExecutorService を使用していくつかの Callable スレッドを実行しています。ExecutorService に送信する前に、スレッドはデータで初期化されます。

Future.get() によってスローされた例外を処理するとき、元のデータでメッセージをログに記録したいと考えています。Future オブジェクトからそれを作成した元のスレッドに戻ることは可能ですか?

疑似コード:

void run(List<Data> dataList) {
    List<Future<Foo>> results = new ArrayList<Future<Foo>>();
    for (Data data : dataList) {
        Callable<Foo> thread = new FooCallable(data);
        Future<Foo> result = this.executorService.submit(thread);
        results.add(result);
    }

    ...

    for (Future<Foo> result : results) {
        Foo foo;
        try {
            foo = result.get();
        } catch (InterruptedException e) {
            //
            // I would like access to the original Data object here
            //
        } catch (ExecutionException e) {
            //
            // and here
            //
        }
    }
}
4

2 に答える 2

0

リストの代わりにマップを使用して、Future とそれに対応するデータを保存し、Future をそのマップへのキーとして使用します。

Map<Future<Foo>,Data> results = new HashMap<Future<Foo>,Data>();
for (Data data : dataList) {
    Callable<Foo> thread = new FooCallable(data);
    Future<Foo> result = this.executorService.submit(thread);
    results.put(result,data);
}

Iterator<Map.Entry<Future<Foo>,Data>> resultsIterator = results.entrySet().iterator();
while(resultsIterator.hasNext()) {
    Map.Entry<Future<Foo>,Data> entry = resultsIterator.next();
    Future<Foo> future = entry.getKey();
    Data data = entry.getValue();
    Foo foo;
    try {
        foo = future.get();
    } catch (InterruptedException e) {
        //data accessible here
    } catch (ExecutionException e) {
        //data accessible here too
    }
}
于 2013-05-24T21:28:52.157 に答える
0

Future オブジェクトからそれを作成した元のスレッドに戻ることは可能ですか?

Data例外の原因となったフィールドにアクセスしたいということだと思います。これを行うには、小さなコンテナ クラスを作成します。

private static class FutureData {
   final Data data;
   final Future<Foo> future;
   public FutureData(Data data, Future<Foo> future) {
      this.data = data;
      this.future = future;
   }
}

次に、未来を作成するときに、代わりにリストに追加FutureDataします。results

List<FutureData> results = new ArrayList<FutureData>();
for (Data data : dataList) {
    Callable<Foo> callable = new FooCallable(data);
    Future<Foo> future = this.executorService.submit(callable);
    results.add(new FutureData(data, future));
}

次に、次のことができます。

for (FutureData futureData : results) {
    Foo foo;
    try {
        foo = futureData.future.get();
    } catch (Exception e) {
       // use futureData.data here
       ...
于 2013-05-24T21:09:47.573 に答える