简体   繁体   English

执行者服务 - 线程超时

[英]Executor Service - timeout of thread

While I was exploring ExecutorService , I encountered a method Future.get() which accepts the timeout . 在我探索ExecutorService ,我遇到了一个接受timeout的方法Future.get()

The Java doc of this method says 这种方法的Java文档说


Waits if necessary for at most the given time for the computation to complete, and then retrieves its result, if available. 如果需要,最多等待计算完成的给定时间,然后检索其结果(如果可用)。

Parameters: 参数:

timeout the maximum time to wait 超时等待的最长时间

unit the time unit of the timeout argument 单位超时参数的时间单位


As per my understanding, we are imposing a timeout on the callable , we submit to the ExecutorService so that, my callable will interrupt after the specified time(timeout) has passed 根据我的理解,我们在callable上强加了一个超时,我们提交给ExecutorService这样,我的callable将在指定的时间(超时)过后中断

But as per below code, the longMethod() seems to be running beyond the timeout(2 seconds), and I am really confused understanding this. 但是根据下面的代码, longMethod()似乎超出了超时(2秒),我很难理解这一点。 Can anyone please point me to the right path? 任何人都可以请我指出正确的道路吗?

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();
        }
    }


}

my callable will interrupt after the specified time(timeout) has passed 我的callable将在指定的时间(超时)过后中断

Not true. 不对。 The task will continue to execute, instead you will have a null string after the timeout. 任务将继续执行,而在超时后您将有一个空字符串。

If you want to cancel it: 如果你想取消它:

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

PS As you have it right now this interrupt will have no effect what so ever. PS正如你现在所拥有的那样,这个中断将不会产生任何影响。 You are not checking it in any way. 你没有以任何方式检查它。

For example this code takes into account interrupts: 例如,此代码考虑了中断:

    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();
    }
}

And then: 接着:

        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();

The timeout on get() is for how long the 'client' will wait for the Future to complete. get()的超时是“客户端”等待Future完成的时间。 It does not have an impact on the future's execution. 它对未来的执行没有影响。

Object result;
int seconds = 0;
while ((result = fut.get.(1, TimeUnit.SECOND)) == null) {
    seconds++;
    System.out.println("Waited " + seconds + " seconds for future";
}

my callable will interrupt after the specified time(timeout) has passed 我的callable将在指定的时间(超时)过后中断

The above statement is wrong, Usually Future.get is blocking. 上面的语句是错误的,通常Future.get是阻塞的。 Specifying the timeout allows you to use it in a non blocking manner. 指定超时允许您以非阻塞方式使用它。

This is useful for instance in time critical applications, if you need a result within let's say 2 seconds and receiving after that means you can't do anything with that. 这对于时间关键型应用程序非常有用,如果你需要一个结果,比如说2秒,那么接收后就意味着你无法做任何事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM