【发布时间】:2017-11-07 16:00:27
【问题描述】:
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),
将确保整个操作的时间限制为 10 秒,但我需要通过对每个单独的并发任务设置 10 秒的限制来对整个操作进行 10 秒的限制。
【问题讨论】:
-
您是否研究过
Connection和Statement对象上可用的网络超时设置?您不能显式取消查询,但可以捕获SQLTimeOut异常。 -
不知道为什么不赞成,但也许代码示例可以最小化并变得更抽象。不过,请始终感谢投反对票,一个遗憾的投反对票会给您带来多达 5 票投反对票的分数,并且您很可能会在不应该投反对票的问题上得到他们。至于问题,Jim 是对的,设置你的 sql 超时并捕获它抛出的异常。
-
为什么要投反对票? SQL 在 jar 库中。我无法修改或任何连接参数。我只能访问线程。我得到的最接近的是 Future.get() 的超时。但主要问题是第一个 Future.get() 的超时将影响后续的 Future.get() - 这意味着第二个线程可以运行比 Future 中提到的超时更长的时间,因为它的超时时间仅在第一个 Future 超时后开始。如何从内部终止线程,对超时或任何其他外部机制进行自我监控?
标签: java multithreading future executorservice callable