Java中导致超时异常时如何获取Future返回 [英] how to get Future return when cause timeout Exception in java
问题描述
我想知道当使用Future和ExecutorService时,如果导致超时异常会导致我得到结果,例如,下面是我的代码
I'm wondering can I get the result when it cause timeout Exception when use Future and ExecutorService, for example, below is my code
package com.example;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.junit.Test;
public class FutureTest {
public static String sayHello() {
try {
Thread.sleep(3000);
return "world";
} catch (Exception e) {
return "hello";
}
}
@Test
public void testTimeoutAndInterrupt() throws Exception {
ExecutorService executorService = new ThreadPoolExecutor(0, Runtime.getRuntime().availableProcessors() * 2, 0,
TimeUnit.SECONDS, new LinkedBlockingQueue<>(10), new BasicThreadFactory.Builder().namingPattern(
"executor-pool-%d").daemon(true).build());
String processName = UUID.randomUUID().toString();
Future<String> future = executorService.submit(
() -> {
return sayHello();
}
);
try {
String result = future.get(2, TimeUnit.SECONDS);
System.out.println("future result:" + result);
} catch (TimeoutException e) {
System.out.println("timeout exception");
} finally {
future.cancel(true);
System.out.println("cancel by future");
}
}
}
当我使用future.get(5,TimeUnit.SECONDS)时,可以按预期获得值世界".现在,当我使用future.get(2,TimeUnit.SECONDS)时,我想要返回的值是"hello".
when I use future.get(5, TimeUnit.SECONDS), It's OK to get value "world" as I expect. now I want get the return value is "hello", when I use future.get(2, TimeUnit.SECONDS) .
我该怎么做?谢谢
推荐答案
不,该异常不会在执行过程中抛出.而是抛出一个 InterruptedException .(在那里尝试使用System.out.println).
No, that exception is not thrown inside the execution. Instead a InterruptedException is thrown. (Try a System.out.println there).
控制流程:
- 执行中发生超时
- 线程被中断
当3a和3b在两个线程中(异步)发生时,顺序可能是3b; 3a.但是3a; 3b似乎是自然顺序.
As 3a and 3b happen in two threads (asynchroneously) the order could be 3b;3a. However 3a;3b seems the natural order.
这样做:
String result;
try {
result = future.get(2, TimeUnit.SECONDS);
System.out.println("future result:" + result);
} catch (TimeoutException e) {
System.out.println("timeout exception");
result = "hello";
} finally {
注意:我认为FutureTask线程不能保证已关闭(因为可能没有捕获,即使捕获之后代码仍会继续).
Notice: I think the FutureTask thread is not guaranteed to have shutdown (as there might not have been a catch, and even then after the catch the code continues).
将catch InterruptedException捕获到某个地方存放结果将失败,因为在捕获TimeoutException时,FutureTask仍然不能具有InterruptedException.
Using catch InterruptedException to somewhere deposit a result, will fail, as at the moment of catching the TimeoutException the FutureTask still can have no InterruptedException.
在每个循环步骤中存储进度时,这也是一个陷阱.捕获超时后,进度可能仍会更新.
This is also a pitfall when storing a progress in every loop step. After catching the timeout the progress might still be updated.
这篇关于Java中导致超时异常时如何获取Future返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!