public class FutureGetTimeoutTest {
private static final ExecutorService THREAD_POOL = Executors.newFixedThreadPool(5);
public static void main(String[] args) throws InterruptedException, ExecutionException {
List<String> respList = new ArrayList<String>();
List<Future<String>> futures = new ArrayList<Future<String>>();
futures.add(THREAD_POOL.submit(new CallableTask(1L)));
futures.add(THREAD_POOL.submit(new CallableTask(2L)));
futures.add(THREAD_POOL.submit(new CallableTask(3L)));
long start = System.currentTimeMillis();
System.out.println(start);
for (Future<String> future : futures) {
try {
respList.add(future.get(10000, TimeUnit.MILLISECONDS));
/*
* Timeout time for 2nd Task starts only at the end of 1st Task Timeout
* and so 2nd task is able to run for 20s and 3rd task for 30s!
*/
} catch (TimeoutException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println(end);
System.out.println(end - start);
System.out.println(respList);
}
}
class CallableTask implements Callable<String> {
private long ipAddressL;
public CallableTask(long ipAddressL) {
this.ipAddressL = ipAddressL;
}
@Override
public String call() throws Exception {
if (ipAddressL == 1) {
Thread.sleep(10000);
/* Imagine a DB operation taking more time. */
return "1";
} else if (ipAddressL == 2) {
Thread.sleep(20000);
return "2";
} else {
Thread.sleep(30000);
return "3";
}
}
}
如果每个任务单独占用超过10秒,我想返回一个空字符串或者只是终止线程或从每个任务中抛出一个TimeoutException。
假设第一个线程需要10秒,Future.get()
将等待10秒然后超时。我将捕获异常并继续迭代第二个未来对象。说第二个线程此时没有完成(这意味着它在第一个线程运行并且仍在运行时运行了10秒),现在第二个线程上的Future.get()
将等待另外10个,所以总共20秒,依此类推后续线程。
future.get(1000, TimeUnit.MILLISECONDS) (1 sec),
将确保整个操作的10s限制,但我需要对每个单独的并发任务设置10s限制整个操作10s。
答案 0 :(得分:1)
使用THREAD_POOL.invokeAll
代替submit
等待10秒才能完成任务。
如果某些任务在10秒之前完成,您可以使用future.isDone()
检查该任务,并使用future.get
检索结果而不会阻止。