8

Thread サブクラスのキャンセル ポリシーの実装について質問があります。次のようにするのが一般的な方法のようです。

class A extends Thread {

  [...]

  public final void run() {
     try {
        while(!Thread.currentThread().isInterrupted()) {
           [...]
        }
     } catch (InterruptedException consumed) {
     }
  }

  public final void cancel() {
     interrupt();
  }    
}

私が持っている質問は Thread.currentThread() に関するものです...中断フラグをチェックするために currentThread() を使用するのが一般的なのはなぜですか? 次のように A の isInterrupted() メソッドを呼び出すだけで十分ではないでしょうか。

while (!isInterrupted()) {
   [...]
}

並列 Java に関する Brian Goetz の優れた本である Thread JavaDoc にも、stackoverflow にも答えが見つかりませんでした。

あなたの洞察を前もってありがとう!

乾杯、ゲオルグ

4

4 に答える 4

18

あなたの場合、クラス!isInterrupted()から拡張しているので、呼び出すだけで十分です。Thread通常、 from を拡張しません。Threadそのため、 を呼び出しますThread.currentThread()

于 2012-07-27T07:05:43.373 に答える
4

Java 5 以降、スレッドを直接操作することはお勧めできません。Executor フレームワークを使用し、要件に応じて実行ポリシーを選択する必要があります。インスタンスisInterrupted()メソッドは、このスレッドが中断されたかどうかをテストします。スレッドの中断状態は、このメソッドの影響を受けません。内部isInterrupted()は実際にはネイティブ メソッドです。

906     public boolean isInterrupted() {
907         return isInterrupted(false);
908     }

エグゼキュータ フレームワークを使用している間、どのスレッド インスタンスが現在コードを実行しているかがわからないため、規則では Thread.currentThread.isInterrupted() を使用します。

于 2012-07-27T07:44:27.500 に答える
2

明確です: ;へのcancel呼び出しを効果的に転送しています。this.interruptつまり、cancelメソッドが適用される Thread インスタンスです。

メソッドに関しては、メソッドが実際に呼び出され、(予想される) のインスタンスによってのみ呼び出されrunたという前提で、あなたが述べたことはすべて意味があります。それはおそらく安全な仮定ですが、それは普遍的に正しいのでしょうか? 今、その仮定がどのように/いつ違反されるかの意味のある例を私に尋ねるつもりなら、この夜遅くに帽子からそれを引き出すことができるかどうかわかりません:-)runclass A

以外の方法を検討してくださいrun。それがメソッドの場合class A、同じスレッドによって/同じスレッドで呼び出されていると想定する必要がありますか? 多分それは別のクラスのメソッドです。したがって、これは潜在的なバグを排除するためのベスト プラクティスにすぎないようです。コードはコピー/貼り付けの防止になります [@Thomas もこの洞察を作成しました]。

于 2012-07-27T07:15:55.697 に答える
1

そのコードが現在実行中のスレッドにある場合は、同じである必要があります。おそらく作者は、誰かが別のスレッドで run メソッドを実行するのではないかと心配しているのかもしれません。または、彼らはそれをコピーして貼り付け、考えませんでした。

于 2012-07-27T07:06:30.027 に答える