在我探索ExecutorService
时,我遇到了一个接受Future.get()
的方法timeout
。
此方法的Java文档说
如果需要,最多等待计算完成的给定时间,然后检索其结果(如果可用)。
参数:
超时等待的最长时间
单位超时参数的时间单位
根据我的理解,我们对callable
施加了超时,我们提交给ExecutorService
,以便我的callable
中断后指定的时间(超时)已经过了
但是根据下面的代码,longMethod()
似乎超出了超时(2秒),我很难理解这一点。任何人都可以请我指出正确的道路吗?
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Timeout implements Callable<String> {
public void longMethod() {
for(int i=0; i< Integer.MAX_VALUE; i++) {
System.out.println("a");
}
}
@Override
public String call() throws Exception {
longMethod();
return "done";
}
/**
* @param args
*/
public static void main(String[] args) {
ExecutorService service = Executors.newSingleThreadExecutor();
try {
service.submit(new Timeout()).get(2, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:12)
我的callable将在指定的时间(超时)过去后中断
不正确。该任务将继续执行,而在超时后您将有一个空字符串。
如果你想取消它:
timeout.cancel(true) //Timeout timeout = new Timeout();
P.S。正如你现在所拥有的那样,这个中断将不会产生任何影响。你没有以任何方式检查它。
例如,此代码考虑了中断:
private static final class MyCallable implements Callable<String>{
@Override
public String call() throws Exception {
StringBuilder builder = new StringBuilder();
try{
for(int i=0;i<Integer.MAX_VALUE;++i){
builder.append("a");
Thread.sleep(100);
}
}catch(InterruptedException e){
System.out.println("Thread was interrupted");
}
return builder.toString();
}
}
然后:
ExecutorService service = Executors.newFixedThreadPool(1);
MyCallable myCallable = new MyCallable();
Future<String> futureResult = service.submit(myCallable);
String result = null;
try{
result = futureResult.get(1000, TimeUnit.MILLISECONDS);
}catch(TimeoutException e){
System.out.println("No response after one second");
futureResult.cancel(true);
}
service.shutdown();
答案 1 :(得分:2)
get()的超时时间是指&#39;客户端&#39;将等待未来完成。它对未来的执行没有影响。
Object result;
int seconds = 0;
while ((result = fut.get.(1, TimeUnit.SECOND)) == null) {
seconds++;
System.out.println("Waited " + seconds + " seconds for future";
}
答案 2 :(得分:0)
在指定的时间(超时)过去后,我的可调用中断
上面的陈述是错误的,通常Future.get是阻塞的。指定超时允许您以非阻塞方式使用它。
这对于时间关键型应用程序非常有用,如果您需要2秒钟内的结果,那么接收后就意味着您无法执行任何操作。