如何使线程超时 [英] How to timeout a thread

查看:27
本文介绍了如何使线程超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在一段固定的时间内运行一个线程.如果在那段时间内没有完成,我想要么杀死它,抛出一些异常,要么以某种方式处理它.怎么办?

I want to run a thread for some fixed amount of time. If it is not completed within that time, I want to either kill it, throw some exception, or handle it in some way. How can it be done?

我从 中发现的一种方法这个话题就是在Thread的run()方法里面使用一个TimerTask.

One way of doing it as I figured out from this thread is to use a TimerTask inside the run() method of the Thread.

有没有更好的解决方案?

Are there any better solutions for this?

 
添加赏金,因为我需要一个更清晰的答案.下面给出的 ExecutorService 代码没有解决我的问题.为什么我应该在执行后 sleep() (一些代码 - 我无法处理这段代码)?如果代码完成并且sleep()被中断,那怎么可能是超时?

 
Adding a bounty as I needed a clearer answer. The ExecutorService code given below does not address my problem. Why should I sleep() after executing (some code - I have no handle over this piece of code)? If the code is completed and the sleep() is interrupted, how can that be a timeOut?

需要执行的任务不在我的控制范围内.它可以是任何一段代码.问题是这段代码可能会陷入无限循环.我不希望这种情况发生.所以,我只想在单独的线程中运行该任务.父线程必须等到该线程完成并需要知道任务的状态(即是否超时或发生异常或是否成功).如果任务进入无限循环,我的父线程会一直无限期地等待,这不是理想的情况.

The task that needs to be executed is not in my control. It can be any piece of code. The problem is this piece of code might run into an infinite loop. I don't want that to happen. So, I just want to run that task in a separate thread. The parent thread has to wait till that thread finishes and needs to know the status of the task (i.e whether it timed out or some exception occured or if its a success). If the task goes into an infinite loop, my parent thread keeps on waiting indefinitely, which is not an ideal situation.

推荐答案

确实不如使用 ExecutorService 而不是 Timer,这是一个 SSCCE:

Indeed rather use ExecutorService instead of Timer, here's an SSCCE:

package com.stackoverflow.q2275443;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class Test {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<String> future = executor.submit(new Task());

        try {
            System.out.println("Started..");
            System.out.println(future.get(3, TimeUnit.SECONDS));
            System.out.println("Finished!");
        } catch (TimeoutException e) {
            future.cancel(true);
            System.out.println("Terminated!");
        }

        executor.shutdownNow();
    }
}

class Task implements Callable<String> {
    @Override
    public String call() throws Exception {
        Thread.sleep(4000); // Just to demo a long running task of 4 seconds.
        return "Ready!";
    }
}

稍微使用 Future#get() 方法,例如将其增加到 5,您将看到线程完成.您可以在 catch (TimeoutException e) 块中拦截超时.

Play a bit with the timeout argument in Future#get() method, e.g. increase it to 5 and you'll see that the thread finishes. You can intercept the timeout in the catch (TimeoutException e) block.

更新:为了澄清概念上的误解,sleep() 不需要.它仅用于 SSCCE/演示目的.只需在那里执行您的长时间运行的任务即可代替 sleep().在您长时间运行的任务中,您应该检查线程是否不是 中断如下:

Update: to clarify a conceptual misunderstanding, the sleep() is not required. It is just used for SSCCE/demonstration purposes. Just do your long running task right there in place of sleep(). Inside your long running task, you should be checking if the thread is not interrupted as follows:

while (!Thread.interrupted()) {
    // Do your long running task here.
}

这篇关于如何使线程超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆