我想知道可以在导致超时时获得结果使用Future和ExecutorService时出现异常,例如,下面是我的代码
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)时,可以像我期望的那样获得价值“世界”。 现在我希望得到的返回值是“hello”,当我使用future.get(2,TimeUnit.SECONDS)时。
我该怎么做?感谢
答案 0 :(得分:1)
不,该异常不会在执行中抛出。而是抛出 InterruptedException 。 (在那里试试System.out.println。)
控制流程:
由于3a和3b发生在两个线程中(异步),顺序可以是3b; 3a。然而3a; 3b似乎是自然顺序。
所以:
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线程不能保证关闭(因为可能没有捕获,甚至在捕获代码后继续)。
使用catch InterruptedException到某个地方存放结果会失败,因为在捕获TimeoutException时FutureTask仍然没有InterruptedException。
在每个循环步骤中存储进度时,这也是一个陷阱。在捕获超时后,进度可能仍会更新。