5

サードパーティのライブラリを使用して、多数のデータセットを処理しています。プロセスは非常にまれに無限ループに入ります(またはブロックされます-理由がわからず、コードに入ることができません)。決められた時間の後にこれを殺して、次のケースに進みたいです。簡単な例は次のとおりです。

for (Object data : dataList) {
    Object result = TheirLibrary.processData(data);
    store(result);
}

processDataは通常、最大1秒かかります。たとえば、10秒後にprocessData()を強制終了するタイマーを設定したい

編集私はコードスニペットをいただければ幸いです(私はスレッドの使用については練習していません)。エグゼキュータのアプローチは便利に見えますが、どのように始めればよいのかよくわかりません。また、より一般的なアプローチの擬似コードは、私がコーディングするには一般的すぎます。

@Steven Schlansker-サードパーティのアプリが割り込みを予期しない限り、それは機能しないことを示唆しています。繰り返しますが、詳細と例をいただければ幸いです

編集私は同僚のサム・アダムズから私が望んでいた正確な解決策を得ました。それは私が答えとして追加しています。他の回答よりも詳細ですが、両方に投票します。サムズを承認済みの回答としてマークします

4

3 に答える 3

10

ExecutorService.invokeAll(...)メソッドの1つは、タイムアウト引数を取ります。ライブラリを呼び出す単一のCallableを作成し、そのメソッドの引数としてリストにラップします。返された未来は、それがどのように進んだかを示しています。

(注:私はテストしていません)

于 2010-08-15T22:27:04.047 に答える
7

ライブラリへの呼び出しを別のスレッドに入れ、タイムアウト後にこのスレッドを強制終了します。そうすれば、複数のオブジェクトが相互に依存していない場合は、それらを同時に処理することもできます。


編集:デモコードリクエスト

これは擬似コードであるため、改善および拡張する必要があります。また、天気予報のエラーチェックで電話が成功したかどうかもわかります。

for (Object data : dataList) {
    Thread t = new LibThread(data);
    // store the thread somewhere with an id
    // tid and starting time tstart 
    // threads
    t.start();
    }

while(!all threads finished)
{
    for (Thread t : threads)
    {
        // get start time of thread
        // and check the timeout
        if (runtime > timeout)
        {
            t.stop();
        }
    }
}

class LibThread extends Thread {
    Object data;

    public TextThread(Object data) 
    {
        this.data = data;
    }

    public void processData() 
    {
        Object result = TheirLibrary.processData(data);
        store(result);
    }
}
于 2010-08-15T22:06:18.440 に答える
2

サム・アダムズは私に次の答えを送ってくれました、それは私の受け入れられたものです

Thread thread = new Thread(myRunnableCode);
thread.start();
thread.join(timeoutMs);
if (thread.isAlive()) {
  thread.interrupt();
}

定期的myRunnableCodeにチェックThread.isInterrupted()し、これがtrueを返す場合はクリーンに終了します。

または、次のことを行うことができます。

Thread thread = new Thread(myRunnableCode);
thread.start();
thread.join(timeoutMs);
if (thread.isAlive()) {
  thread.stop();
}

ただし、このメソッドは危険であるため、非推奨になっています。

http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#stop() "このメソッドは本質的に安全ではありません。Thread.stopでスレッドを停止すると、すべてのロックが解除されますロックされたモニターの(スタックを伝播する未チェックのThreadDeath例外の自然な結果として)これらのモニターによって以前に保護されたオブジェクトのいずれかが一貫性のない状態にあった場合、損傷したオブジェクトが他のスレッドに表示され、結果として生じる可能性があります任意の振る舞いで。」

私は2番目を実装しました、そしてそれは私が現在望むことをします。

于 2010-08-16T12:10:43.710 に答える