2016-09-05 5 views
1

スレッドgetが待機状態になるまで待つ必要があります。私はjoin(以下を参照)を使用しようとしていましたが、動作しませんでした。これを達成する方法は?スレッドが待機するのを待つ方法

public Test() { 
    System.out.print("Started"); 
    Thread thread = new Thread(() -> { 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     synchronized (Test.class) { 
      try { 
       Test.class.wait(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
    thread.start(); 

    try { 
     thread.join(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    System.out.print("Done"); 
} 

完了は決して印刷されません。

+0

これは、Test.classが通知されないためです。あなたは正確に何をしようとしていますか?いくつかの非同期操作が完了するのを待ちますか?次に、先物を使用してください... – Fildor

+0

あなたのスレッドは何も役に立たず、必要ではないことを実感しているので、これはあなたが何をしようとしているかを実証していません。 –

+0

私はカウントダウンラッチを調べることをお勧めします。以前はGUIとSwingWorkersに同様の問題がありました。ラッチの仕組みは、必要な数を定義することです(2つのスレッドがある場合は、入力パラメータ2を持つ単一のラッチが必要です)。ラッチをスレッドのコンストラクタに渡し、スレッドが終了したらlatch.countdown()を実行します。プログラムの主要部分では、latch.wait()を実行します。ラッチが0に達すると、プログラムは続行されます。これが助けてくれることを願っています – Zeliax

答えて

1

メインスレッドはjoin()を超えて進まず、2番目のスレッドは終了しないためです。 2番目のスレッドは、Test.classの通知を待っているために終了しませんが、誰も通知しません。

2番目のスレッドがTest.class.wait();行に達したときにメインスレッドを実行し続けるには、この同期のために別のモニターを導入する必要があります。メインスレッドはこのモニタ上で待機しなければならないし、それが待っている状態に切り替える準備ができているときに、第2のスレッドがそれを通知しなければならない:

System.out.println("Started"); 
final Object monitor = new Object(); 
Thread thread = new Thread(() -> { 
    try { 
     Thread.sleep(1000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    System.out.println("Finished"); 
    synchronized (monitor) { 
     monitor.notify(); // Notify the main thread 
    } 
    synchronized (Test.class) { 
     try { 
      Test.class.wait(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
}); 
thread.start(); 

synchronized (monitor) { 
    try { 
     monitor.wait(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 
System.out.println("Done"); 

このコードは動作しますが、それは少し醜いのに。また、プログラムが正常に終了するのを妨げる懸垂スレッドが残されます。このスレッドを終了させるには、Test.class.notify()に電話する必要があります。

一般的に達成しようとしていることはあなたの質問からは分かりません。あなたがスレッドを生成し、それが終了されるまで待ちたい場合は、それらのwait() sおよびnotify()秒を必要としない、ちょうどjoin()を使用します。

System.out.println("Started"); 
Thread thread = new Thread(() -> { 
    try { 
     Thread.sleep(1000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    System.out.println("Finished"); 
}); 
thread.start(); 

try { 
    thread.join(); 
} catch (InterruptedException e) { 
    e.printStackTrace(); 
} 
System.out.println("Done"); 

そしてもう一つ:コンストラクタでスレッドを作成して開始することは、Aであります非常に悪い考え。これには別の方法(initialize()など)を使用します。

+0

あなたの最初の例で私を得ました、私はちょうどそこにいくつかのネイティブの代替が望んでいます...しかし、あなたの提案も良いようです! Tnx。 –

関連する問題