6

在探索的过程ExecutorService中,我遇到了一种Future.get()接受timeout.

这种方法的Java doc说


如有必要,最多等待给定时间以完成计算,然后检索其结果(如果可用)。

参数:

timeout等待的最长时间

unit超时参数的时间单位


根据我的理解,我们对 施加超时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();
        }
    }


}
4

3 回答 3

14

在指定的时间(超时)过去后,我的可调用对象将中断

不对。该任务将继续执行,但超时后您将获得一个空字符串。

如果你想取消它:

  timeout.cancel(true) //Timeout timeout = new Timeout();

PS正如你现在所拥有的那样,这个中断不会有任何影响。你没有以任何方式检查它。

例如,此代码考虑了中断:

    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();
于 2013-04-29T11:15:35.070 回答
3

get() 的超时时间是“客户端”等待 Future 完成的时间。它对未来的执行没有影响。

Object result;
int seconds = 0;
while ((result = fut.get.(1, TimeUnit.SECOND)) == null) {
    seconds++;
    System.out.println("Waited " + seconds + " seconds for future";
}
于 2013-04-29T11:16:11.817 回答
0

在指定的时间(超时)过去后,我的可调用对象将中断

上面的说法是错误的,通常 Future.get 是阻塞的。指定超时允许您以非阻塞方式使用它。

例如,这在时间关键型应用程序中很有用,如果您需要在 2 秒内得到结果,并且在此之后接收意味着您无法对此做任何事情。

于 2013-04-29T11:16:22.693 回答