これにはクリーンアップが必要になる可能性がありますが、問題は解決するはずです。(時間と空間のために省略された一部のカプセル化):
public static <T> LatchWithWrappedCallables<T> wrapCallables(Collection<Callable<T>> callablesToWrap)
{
CountDownLatch latch = new CountDownLatch(callablesToWrap.size());
List<Callable<T>> wrapped = new ArrayList<Callable<T>>(callablesToWrap.size());
for (Callable<T> currCallable : callablesToWrap)
{
wrapped.add(new CallableCountdownWrapper<T>(currCallable, latch));
}
LatchWithWrappedCallables<T> returnVal = new LatchWithWrappedCallables<T>();
returnVal.latch = latch;
returnVal.wrappedCallables = wrapped;
return returnVal;
}
public static class LatchWithWrappedCallables<T>
{
public CountDownLatch latch;
public Collection<Callable<T>> wrappedCallables;
}
public static class CallableCountdownWrapper<T> implements Callable<T>
{
private final Callable<T> wrapped;
private final CountDownLatch latch;
public CallableCountdownWrapper(Callable<T> wrapped, CountDownLatch latch)
{
this.wrapped = wrapped;
this.latch = latch;
}
@Override
public T call() throws Exception
{
try
{
return wrapped.call();
}
finally
{
latch.countDown();
}
}
}
次に、コードは次のように呼び出します。
Collection<Callable<String>> callablesToWrap = [Your callables that you need to wait for here];
LatchWithWrappedCallables<String> latchAndCallables = wrapCallables(callablesToWrap);
[Submit the wrapped callables to the executors here]
if(latchAndCallables.latch.await(timeToWaitInSec, TimeUnit.SECONDS))
{
[Handling for timeout here]
}