2017-05-09 6 views
1

コードだけmain()で新しいスレッドを開始した後、wait()を呼び出すとメインスレッドをブロックできませんか?

static class ThreadA extends Thread { 
    public ThreadA(String name) { 
     super(name); 
    } 

    @Override 
    public void run() { 
     synchronized (this) { 
      System.out.println(Thread.currentThread().getName() + " call notify()"); 
     } 
    } 
} 

public static void main(String[] args) throws InterruptedException { 
    ThreadA t1 = new ThreadA("t1"); 

    synchronized (t1) { 
     System.out.println("start: " + Thread.currentThread().getName()); 
     t1.start(); 

     t1.wait(); 
     System.out.println(" -- end -- "); 
    } 
} 

と出力されている参照してください。あなたがThread.join()で必要なものメインスレッド

+0

メインスレッドをブロックしていますが、何とか解放されています。 t1は実行を終了するので、メインスレッドは最後のスレッドである必要があります。 – matt

+0

しかし、同期されたボルクの中でwaitを呼び出すと、メインスレッドがブロックされます。@ matt – chasel

+0

はい、メインスレッドがブロックされた後、別のスレッドが実行されて何らかの理由でメインスレッドが起動します。これは、偽のウェークアップが存在する可能性があるため、waitを使用することをお勧めします。したがって、whileループの提案または 'join 'の提案。 – matt

答えて

1

をブロックしません)

start: main 
t1 call notify() 
-- end -- 

理由(待機を呼び出します。 Object.wait()の目的は、そのオブジェクトのモニタロックが別のスレッドによって解放されるまで(Object.notify()またはObject.notifyAll()を使用して)待つことです。

public static void main(String[] args) throws InterruptedException { 
    ThreadA t1 = new ThreadA("t1"); 

    synchronized (t1) { 
     System.out.println("start: " + Thread.currentThread().getName()); 
     t1.start(); 

     t1.join(); 
     System.out.println(" -- end -- "); 
    } 
} 
+0

これは奇妙ではない、この例では 'notify'が呼び出されていますか?スレッドは完了すると通知しますか?それは同期ブロックを残すことと関係がありますか? – matt

+0

私は知っている限り、メインスレッドがブロックではないことを知りたいのですが、notify/notifyAllを呼び出さない限り、現在のスレッドはwait()の後でブロックされます。 – chasel

+0

待機と結合は異なる用途を持っています。結合は、中断するまで待機するか、結合されたスレッドがブロックを実行して終了します。しかし、ノーフィーが得られたら待ってください。例外スローはなく、プログラマはスレッドの状態が異なっていることを知っています。 –

2

あなたの質問への答えはjoin(long millis)方法のjavadocの見つけることができます:

この実装はthis.isAliveを条件this.wait呼び出しのループを使用しています。 スレッドが終了すると、this.notifyAllメソッドが呼び出されます。アプリケーションは、スレッドインスタンスに対してwait、notify、またはnotifyAllを使用しないことをお勧めします。

(強調鉱山)

ので:あなたのメインループは、それが終了すると、それは自分自身の呼び出しnotifyAllに待っているスレッドとして、待って停止します。

他の人が既に指摘したように、スレッドが終了するのを待つ適切な方法は、joinを呼び出すことです。

+0

ありがとう – chasel

関連する問題