0

Javaで一連の命令のタイムアウトを設定することは可能ですか?私は次のものを持っています:

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

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

ループのタイムアウトを設定したいのですが、時間に達した場合は、通常どおりinstructions2を続行します。ループ内にはいくつかの関数呼び出し(少し複雑な組織)があり、それらのいずれか内でブロックされる可能性があり、その結果、ループが長くなります。

前もって感謝します。

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

for ループ内のどこかでキャッチしている場合はInterruptedException、それらの try/catch ブロックをすべて削除し、代わりに for ループ全体を囲む単一の try/catch を作成します。これにより、スレッドを中断したときに for ループ全体を停止できます。

同様に、 catch の場合はIOException、catch InterruptedIOExceptionand ClosedByInterruptExceptionfirst. これらの catch ブロックを for ループの外に移動します。IOException(外部レベルでキャッチするものが何もないため、内部でキャッチしている場合、コンパイラはそれを許可しません。)

ブロッキング呼び出しが throwingInterruptedExceptionでない場合は、次のように、それぞれの後にチェックを追加する必要があります。

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 に答える
1

おそらく、この例はあなたを助けることができます

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

    for(;;){

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

    }

費やした時間を数えて、ループを離れることができます。

もう 1 つの戦略は、指定された時間の経過後にスレッドを中断することです。これが役立つことを願っています

于 2012-11-29T11:26:28.967 に答える