次のコードは、5 つのスレッドを起動し、3 番目のスレッドにフラグを設定して、それが唯一継続することを示します。次に、同じロック オブジェクトを待機しているすべてのスレッドにlock
通知 (ウェイクアップ) されますが、選択された 1 つのスレッドだけが続行されます。マルチスレッド アプリケーションの作成はまったく簡単ではないことに注意してください (適切な同期、誤ったウェイクアップの処理など)。グループから特定のスレッドを 1 つだけウェイクアップする必要はありません。とにかく、どうぞ...
package test;
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.start(5);
}
private void start(int n) {
MyThread[] threads = new MyThread[n];
for (int i = 0; i < n; i++) {
threads[i] = new MyThread();
/* set the threads as daemon ones, so that JVM could exit while they are still running */
threads[i].setDaemon(true);
threads[i].start();
}
/* wait for the threads to start */
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
/* tell only the third thread that it is able to continue */
threads[2].setCanContinue(true);
/* wake up all threads waiting on the 'lock', but only one of them is instructed to continue */
synchronized (lock) {
lock.notifyAll();
}
/* wait some time before exiting, thread two should be able to finish correctly, the others will be discarded with the end of the JVM */
for (int i = 0; i < n; i++) {
try {
threads[i].join(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("Done!");
}
/** synchronization object, i.e. a lock which makes sure that only one thread can get into "Critical Section" */
private final Object lock = new Object();
/** A simple thread to demonstrate the issue */
private final class MyThread extends Thread {
private volatile boolean canContinue;
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " going to wait...");
synchronized (lock) {
while (!canContinue) {
try {
lock.wait(1000); /* one second */
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
System.out.println(Thread.currentThread().getName() + " woken up!");
}
public void setCanContinue(boolean canContinue) {
this.canContinue = canContinue;
}
};
}
コードの出力は次のとおりです。
スレッド 0 は待機します...
スレッド 2 待機中...
スレッド 3 待機中...
スレッド 1 は待機します...
スレッド 4 待機中...
スレッド 2 が目覚めた!
終わり!
したがって、3 番目のスレッド (0 から始まるインデックス) だけが起動されていることがはっきりとわかります。コードのすべての特定の行を理解するには、Java の同期とマルチスレッドについてさらに詳しく調べる必要があります (たとえば、こちら)。
私はあなたをもっと助けたいと思っていますが、Javaスレッドについてほとんど本を書かなければならないので、スレッドに関するこのJavaチュートリアルを指摘したのはそのためです。そうです、特に初心者にとって、この問題はまったく簡単ではありません。したがって、参照されているチュートリアルを読むことをお勧めします。そうすれば、上記のコードのほとんどを理解できるはずです。簡単な方法はありません。少なくとも私は知りません。