3

Runnableインターフェースを実装するオブジェクトがいくつかあり、それらを別々のThreadsで実行します。基本的にrun()、Runnable オブジェクトのメソッドで、(ネットワークからの) 入力を待機している間にブロックするメソッドの呼び出しを含むいくつかのネットワーク アクティビティを実行します。Thread.sleep()意図的な一時停止、つまり呼び出しがないことに注意してください。一時停止は、ブロックする可能性のあるメソッドの呼び出しによって発生します。

これらのRunnableオブジェクトはGUIの制御下にあるため、GUIインターフェイスとユーザーに提供したい機能の1つは、Runnableオブジェクトを実行しているスレッドを終了する機能ですが、これを行う方法を理解できません。

明白な手段の 1 つは、Runnable オブジェクト Thread の Thread.interrupt() メソッドを呼び出すことですが、この Thread メソッドへの呼び出しはどのようにして Runnable オブジェクトに伝達されるのでしょうか? たとえば、私は try-catch を使用できませんInterruptedException。Runnable オブジェクトでのキャッチは許可されていないようです。私のIDE(netbeans)は、メソッドInterruptedExceptionで決してスローされないと文句を言います。run()

私のコードは以下のとおりで、簡潔にするために削除されています。次の行は、GUI スレッドの GUI コードで実行されます。

digiSearch = new DigiSearch(hostIP,this);
digiSearchThread = new Thread(digiSearch);
digiSearchThread.start();

以下は私のRunnableクラスであり、実行中のスレッドの中断をキャプチャしたい/キャプチャする必要がある場所です。

public class DigiSearch implements Runnable {

private String networkAdapterIP;
private DigiList digiList;

public DigiSearch (String ipAddress, DigiList digiList){
    networkAdapterIP = ipAddress;
    this.digiList = digiList;
}
@Override
public void run() {
    
    try{
        /*
 * Do some network and other activities here which includes calling some blocking methods.  However I would like to interrupt the run() method if possible by calling Thread.interrupt()
*/
                    
            
    }  catch (Exception ex){
       digiList.digiListException(ex);
    } catch (Throwable t){
       System.out.println("Search thread interrupted");
    }
}

}

これを達成する方法や、スレッドを中断するという私の誤解を解決する方法について誰かが教えてくれますか?

4

2 に答える 2

6

スローするブロッキングメソッドはありますIOExceptionか?もしそうなら、これはおそらくあなたのInterruptedExceptionプレースホルダーです。これらのメソッドの多くInterruptedExceptionは導入前に作成されたため、レガシーコードを壊すインターフェイスを更新するのではなく、をラップしInterruptedExceptionますIOException

そうでない場合、あなたはちょっと立ち往生しています。たとえば、動作Runnableするだけでスリープしない無限ループを作成するを作成する場合、このスレッドを中断しても。は発生しませんInterruptedExceptionRunnable定期的にチェックするのが責任ですThread.interrupted()

于 2012-11-20T14:35:08.040 に答える
4

ここで注意すべき点がいくつかあります。

1)ユーザーがスレッドの実行を停止する機能があると便利であることに同意しますが、スレッドがすでに実行しているアクションについて考えることをお勧めします。アクションをロールバックすることは可能ですか? アクションを無視して実行を停止することは可能ですか?

2) Thread.stop() および Thread.destroy() などは非推奨のメソッドです ( http://docs.oracle.com/javase/6/docs/api/ )

では、通常、スレッドの実行をどのように中断するのでしょうか? 揮発性の状態変数を入力します。

public class MyClass implements Runnable {
    private volatile boolean isAlive=true;

   /**
    * Request thread stop by calling requestThreadStop() externally.
    */
    public void requestThreadStop() {
        isAlive = false;
    }

    @Override
    public void run() {
        while(isAlive) {
            //Do All your thread work
            //if isAlive is modified, the next iteration will not happen
        }
    }
}

多くのユースケースで、上記の実装が機能します。ただし、run() メソッド ループ内の作業が 1 回の繰り返しであり、かなりの時間ブロックされる可能性がある場合、ユーザーは操作が完了するまで待機する必要があります。

ユーザーが GUI から終了を要求すると、すぐにスレッドの実行を静かに破棄する方法はありますか? 多分。そのためには、スレッドプールを使用して調べる必要があります。ExecutorService を使用すると、shutdown() および shutdownNow() メソッドにフックを提供できます。

繰り返しを避けるために、スレッドプールのこの機能の詳細については、以前のスタックオーバーフローの投稿How to stop the execution of Executor ThreadPool in java? を参照してください。

于 2012-11-20T15:17:13.803 に答える