0

是否可以在java中为一组指令设置超时?我有以下内容:

    new Thread(new Runnable(){
            public void run() {
                    //instructions
                    for(...){

                     ....
                    }
                    //instructions2
            }}).start();

我想为循环设置一个超时时间,如果它达到时间,请按照指令2正常继续。在循环内部,我有几个函数调用(一个复杂的组织),并且可以在其中任何一个内部被阻塞,从而导致持续时间长的循环。

提前致谢。

4

3 回答 3

2

假设您的阻塞函数响应中断,您可以使用带有超时的未来。如果他们没有,你可以做的不多......请注意,使用下面的方法,您不再需要手动启动线程。

    ExecutorService forLoopExecutor = Executors.newSingleThreadExecutor();
    Future<?> future = forLoopExecutor.submit(new Runnable() {

        @Override
        public void run() {
            //your for loop here
        }
    });
    try {
        future.get(1, TimeUnit.SECONDS); //your timeout here
    } catch (TimeoutException e) {
        future.cancel(true);
    }
    forLoopExecutor.shutdownNow();
    //proceed with the rest of your code
    forLoopExecutor.submit(aRunnableForInstructions2);
于 2012-11-29T11:21:33.210 回答
1

也许这个例子可以帮助你

    long l = System.currentTimeMillis();
    final long TIMEOUTMILLIS = 1000;

    for(;;){

        System.out.println("bla bla bla");
        if(System.currentTimeMillis()>l+TIMEOUTMILLIS){
            break;
        }

    }

您可以计算花费的时间并离开循环。

另一种策略是在指定的时间后中断线程。我希望这有帮助

于 2012-11-29T11:26:28.967 回答
1

如果您InterruptedException在 for 循环内的任何地方捕获,请删除所有这些 try/catch 块,而是使用一个包围整个 for 循环的 try/catch。当您中断其线程时,这将允许整个 for 循环停止。

同样,如果您正在捕捉IOException,请先捕捉InterruptedIOExceptionClosedByInterruptException。将这些 catch 块移到 for 循环之外。(如果您在内部捕获,编译器将不允许它IOException,因为在外部级别没有什么可以捕获的。)

如果阻塞调用没有抛出InterruptedException,则需要在每个调用之后添加一个检查,如下所示:

if (Thread.interrupted()) {
    break;
}

如果您有许多级别的循环,您可能需要添加一个标签,以便您可以直接退出第一个“指令”循环,而无需添加大量标志变量:

instructions:
for ( ... ) {
    for ( ... ) {
        doLongOperation();
        if (Thread.interrupted()) {
            break instructions;
        }
    }
}

无论哪种方式,一旦处理了中断,您就可以让后台线程中断您的第一个 for 循环:

final Thread instructionsThread = Thread.currentThread();
Runnable interruptor = new Runnable() {
    public void run() {
        instructionsThread.interrupt();
    }
};
ScheduledExecutorService executor =
    Executors.newSingleThreadScheduledExecutor();
executor.schedule(interruptor, 5, TimeUnit.MINUTES);

// instructions
try {
    for ( ... ) {
    }
} catch (InterruptedException |
         InterruptedIOException |
         ClosedByInterruptException e) {
    logger.log(Level.FINE, "First loop timed out.", e);
} finally {
    executor.shutdown();
}

// instructions2
于 2012-11-29T12:10:41.387 回答