これはある種の Java Puzzler で、私が偶然見つけたもので、実際には説明できません。たぶん誰かができますか?
次のプログラムは、しばらくするとハングします。2 回出力した後、80 回出力した後ということもありますが、ほとんどの場合、正しく終了する前に発生します。初めて実行しない場合は、数回実行する必要がある場合があります。
public class Main {
public static void main(String[] args) {
final WorkerThread[] threads = new WorkerThread[]{ new WorkerThread("Ping!"), new WorkerThread("Pong!") };
threads[0].start();
threads[1].start();
Runnable work = new Runnable() {
private int counter = 0;
public void run() {
System.out.println(counter + " : " + Thread.currentThread().getName());
threads[counter++ % 2].setWork(this);
if (counter == 100) {
System.exit(1);
}
}
};
work.run();
}
}
class WorkerThread extends Thread {
private Runnable workToDo;
public WorkerThread(String name) {
super(name);
}
@Override
public void run() {
while (true){
if (workToDo != null) {
workToDo.run();
workToDo = null;
}
}
}
public void setWork(Runnable newWork) {
this.workToDo = newWork;
}
}
ここで、ビジーな待機ループが一般的には良い考えではないことは明らかです。しかし、これは改善ではなく、何が起こっているのかを理解することです。
フィールドが に設定されている場合、またはフィールドが に設定されているWorkerThread.setWork()
場合、すべてが期待どおりに機能するため、メモリの問題が疑われます。synchronized
WorkerThread.workToDo
volatile
しかし、なぜそれが起こっているのでしょうか?デバッグは役に立ちません。ステップスルーを開始すると、すべてが期待どおりに動作します。
説明をいただければ幸いです。