Java-超时长时间运行的可调用线程
将确保整个操作的10秒限制,但我需要对整个操作的10秒限制,因为每个并发任务都有10秒的限制。使用Java-超时长时间运行的可调用线程,java,multithreading,future,executorservice,callable,Java,Multithreading,Future,Executorservice,Callable,将确保整个操作的10秒限制,但我需要对整个操作的10秒限制,因为每个并发任务都有10秒的限制。使用线程池。调用all而不是提交以等待任务完成10秒 如果某些任务在10秒内完成,您可以使用future.isDone()检查,并使用future.get检索结果,而不阻塞。您是否研究了连接和语句对象上可用的网络超时设置?您不能显式取消查询,但可以捕获SQLTimeOut异常。不知道为什么会有否决票,但可能可以将代码示例最小化并使其更抽象一些。尽管如此,还是要感谢那些被否决的选票,一张赞成票会给你5张反
线程池。调用all
而不是提交
以等待任务完成10秒
如果某些任务在10秒内完成,您可以使用
future.isDone()
检查,并使用future.get
检索结果,而不阻塞。您是否研究了连接
和语句
对象上可用的网络超时设置?您不能显式取消查询,但可以捕获SQLTimeOut
异常。不知道为什么会有否决票,但可能可以将代码示例最小化并使其更抽象一些。尽管如此,还是要感谢那些被否决的选票,一张赞成票会给你5张反对票的分数,你很可能会在不应该被否决的问题上得到他们的分数。至于这个问题,Jim是对的,设置sql超时并捕获它抛出的异常。为什么要否决投票呢?SQL在jar库中。我无法修改或删除任何连接参数。我只能访问线程。我得到的最接近的结果是Future.get()的超时。但主要的问题是第1个Future.get()的超时将影响后续的Future.get()-这意味着第2个线程可以运行比将来提到的超时更长的时间,因为它的超时时间只在第1个Future的超时之后开始。如何从线程自身内部终止线程,对超时或任何其他外部机制进行自我监控?如果至少有一个任务
占用的时间超过超时时间,则建议使用超时。我可能经常得到一个长期运行的任务。因此,我不想拒绝其他短期运行任务的结果。我需要的是每个任务都有一个超时,并且只忽略长时间运行的超时任务的结果——并且需要这个超时是绝对的,而不是像Future.get()中那样是相对的。这确保了所花费的总时间也大约小于10秒,更重要的是,我可以利用短期运行任务的结果,而不是丢弃所有任务。invokeAll将阻塞主线程,直到所有任务完成。让我在主线程中尝试使用CountDownLatch
,在submit
-调用所有可调用任务后超时。迭代并检查future.isDone
和get
只有isDone
是正确的。我说的是这一个:invokeAll(CollectionI认为如果invokeAll
超时,我将丢失所有结果。但是长时间运行的线程(DB读取我无法控制的DB Infra jar库中的查询)会吗超时后立即停止?我想,没有,必须显式地处理中断。如果是循环,每次迭代都可以检查中断。但是,如果线程正在等待DB读取结果,如何实现中断?这将是一个问题,因为我的ExecutorService
\线程池将很快达到其极限(所以我必须创建一个大的线程池大小?)。您不会丢失结果。请参阅invokeAll的javadocs(Collection,long,TimeUnit
,特别是:返回表示任务的未来列表,其顺序与迭代器为给定任务列表生成的顺序相同。如果操作未超时,则每个任务都已完成。如果操作超时,则其中一些任务将未完成。
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";
}
}
}
future.get(1000, TimeUnit.MILLISECONDS) (1 sec),