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

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

问题描述

我想在一段固定的时间内运行一个线程。如果它没有在那段时间内完成,我想杀死它,抛出一些异常,或以某种方式处理它。如何做到这一点?

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()被中断,那怎么可能是timeOut?

 
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 而不是计时器,这是一个 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天全站免登陆