4

だから私は「トリッキーな」質問をしています。人々の意見を見たいのです。

JPanel を拡張し、いくつかのカスタム処理を行うコンポーネントをプログラミングしています。そのコンポーネント内には、次のように永遠にループするスレッドがあります。

//chat thread
    Thread chat_thread = new Thread(new Runnable(){
        public void run(){
            while(true){
                //get chat updates
            }
        }
    });
    chat_thread.start();

問題は、remove()メソッドによってコンポーネントがその親から削除されたとき、このスレッドはまだ生きているのか、それともコンポーネントを削除したときに死ぬのかということです。

編集:
返信ありがとうございます。実際、スレッドはスターターの削除を終了しないため、別のコンポーネントからこのスレッドを終了するために、次のことを行いました:

Set<Thread> t = Thread.getAllStackTraces().keySet();
    Iterator it = t.iterator();
    while(it.hasNext()){
        Thread t2 = (Thread)it.next();
        if(t2.getName().equals("chat_thread")){
            t2.interrupt();
        }
    }

最初に Thread.setName() メソッドでスレッドの名前を作成します。ありがとう!

4

5 に答える 5

4

このスレッドが死ぬことはありません (クラッシュまたは終了しない限り)。

それを開始したスレッド、またはそれを含むコンポーネントに何が起こってもかまいません。

JVM をハングさせたくない場合は、それをデーモン スレッドとして宣言できます。その後、他のすべてがシャットダウンするとシャットダウンします。さらに制御するには、適切なタイミングで独自のコードでスレッドを終了する必要があります。

于 2012-06-09T06:49:22.300 に答える
4

それはまだ生きているでしょう。実行中のスレッドは、GC のルートを構成します。ルートから始まる一連の参照から到達可能なすべてのものは、GC の対象になりません。これは、ところで、スレッドがパネルへの暗黙的な参照を保持しているため、パネルも GC されないことを意味します ( EnclosingPanel.this)。

スレッドをもう実行したくない場合は、必ずスレッドを停止する必要があります。

于 2012-06-09T06:49:57.557 に答える
1

スレッドはその run() メソッドを終了すると終了するため、remove() メソッドによってコンポーネントがその親から削除されても、スレッドは決して終了しません。

于 2012-06-09T07:05:03.080 に答える
1

スレッドは、その作業が終了するまで死ぬことはありませんinterrupt

于 2012-06-09T06:51:29.257 に答える
0

Component.removeNotify を見てください。コンポーネントで、スレッドへのポインターを保持します。

public class MyPanel extends JPanel {
   private Thread thread = ...;

   public void removeNotify() {
      super.removeNotify();
      thread.interrupt();
   }
}

このメソッドは、コンポーネントのネイティブ ピア (つまり、awt コンポーネントをサポートする Windows または Linux コンポーネント) を削除することを決定したときに、awt 自体によって呼び出されます。javadocに従って:

ネイティブの画面リソースを破棄して、この Component を表示できないようにします。このメソッドはツールキットによって内部的に呼び出され、プログラムから直接呼び出されるべきではありません。このメソッドをオーバーライドするコードは、オーバーライドするメソッドの最初の行として super.removeNotify を呼び出す必要があります。

于 2012-06-10T01:22:01.020 に答える