在java中为方法创建超时的最佳方法是什么?

时间:2011-04-27 06:31:32

标签: java multithreading

我想在x秒后停止该方法。 我该怎么做 ?

EDIT
我会详细说明: 我的方法()是本机的或与其他服务器通信 我不在循环中(因此我无法改变旗帜) 我想要使​​用方法的返回值(如果存在)。

4 个答案:

答案 0 :(得分:2)

这在很大程度上取决于你的方法在做什么。最简单的方法是定期检查方法执行的时间,并在超过限制时返回。

long t0 = System.currentTimeMillis();
// do something
long t1 = System.currentTimeMillis();
if (t1-t0 > x*1000) {
    return;
}

如果你想在一个单独的线程中运行该方法,那么你可以这样做:

public <T> T myMethod() {
    ExecutorService executor = Executors.newSingleThreadExecutor();
    try {
        try {
            T value = executor.invokeAny(Collections.singleton(new Callable<T>() {
                @Override
                public T call() throws Exception {
                    //your actual method code here
                    return null;
                }
            }), 3, TimeUnit.SECONDS);
            System.out.println("All went fine");
            return value;
        } catch (TimeoutException e) {
            System.out.println("Exceeded time limit, interrupted");
        } catch (Exception e) {
            System.out.println("Some error happened, handle it properly");
        }
        return null; /*some default value*/
    } finally {
        executor.shutdownNow();
    }
}

请注意,如果您在线程中执行了一些不可中断的IO,则此方法将无效..

答案 1 :(得分:1)

最可靠的方法 - 我认为 - 是一种多线程解决方案。我将长时间运行的算法放在Runnable中并使用ExecutorService执行具有给定超时的线程。

this question的答案提供了有关解决方案的更多详细信息。

当然,现在该方法将与主线程并行执行,但您可以使用Thread#join强制单线程行为 - 只需等待主线程直到时间限制工作线程已经完成或超过了它的超时限制。

答案 2 :(得分:0)

这取决于你正在做什么以及你需要多准确。 如果您处于循环中,则可以使用System.currentTimeMillis()跟踪已经过了多长时间。只需花时间开始并定期检查并查看已经过了多长时间。

您可以生成一个新线程来开始处理,休眠x秒然后做一些事情来停止处理线程。

答案 3 :(得分:0)

你不能在单次执行中这样做,你必须使用线程

我同意armandino

see this