2つのスレッドを持つThreadManagerがあります。1つはGUI関連のリクエスト用で、もう1つは測定関連のリクエスト用です。は、リクエストのキューを実行およびチェックしています。存在する場合は、リクエストを処理しています。ThreadManager.addGuiRequest(eGuiRequest)
staticメソッドとメソッドを使用して、いつでもリクエストを追加できますThreadManager.addMeasRequest(eMeasRequest)
。ここで、これらの両方を初期化する必要があります。これはINIT
、対応するキューに要求を追加することによって行われます。ただし、測定の初期化は、GUIがすでに初期化されているという事実に依存しています。を使用してこれを解決しようとしましたが、機能さwait()/notify()
せることができません。
これがSSCCEです。起動時に、両方のキューにINIT要求が追加されてから、開始されます。測定の初期化は、GUIがまだ初期化されていないことを検出し、aを実行しwait()
ます。GUIが初期化されます(5秒間スリープすることでシミュレートされます)。これはすべて正常に機能します。
GUIが初期化された後、測定スレッドをウェイクアップしようとしますが、測定スレッドはウェイクアップしません...私はこの記事wait()/notify()
に基づいてコードを作成しました。ここで何が問題になっていますか?
import java.util.LinkedList;
import java.util.NoSuchElementException;
public class ThreadManager {
public static void main(String[] args) {
new ThreadManager();
ThreadManager.addMeasRequest(eMeasRequest.OTHER_STUFF);
}
public enum eGuiRequest { INIT, OTHER_STUFF; }
public enum eMeasRequest { INIT, OTHER_STUFF; }
private static LinkedList<eGuiRequest> guiQueue = new LinkedList<eGuiRequest>();
private static LinkedList<eMeasRequest> measQueue = new LinkedList<eMeasRequest>();
private static Thread guiThread, measThread;
protected boolean initialized = false;
public ThreadManager() {
final int waitMs = 200;
guiThread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
if (guiQueue.isEmpty()) sleepMs(waitMs);
else {
eGuiRequest req = guiQueue.getFirst();
processGuiRequest(req);
guiQueue.removeFirst();
}
} catch (NoSuchElementException e) {}
}
}
private void processGuiRequest(eGuiRequest req) {
System.out.println("T: " + "Processing Gui request: " + req);
switch (req) {
case INIT:
// do some initializiation here - replaced by a wait:
sleepMs(5000);
System.out.println("I: " + "guiThread finished, waking up measThread");
synchronized (measThread) {
initialized = true;
measThread.notify();
}
break;
case OTHER_STUFF:
// do other stuff
break;
}
}
});
measThread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
if (measQueue.isEmpty()) sleepMs(waitMs);
else {
eMeasRequest req = measQueue.getFirst();
processMeasurementRequest(req);
measQueue.removeFirst();
}
} catch (NoSuchElementException e) {}
}
}
private void processMeasurementRequest(eMeasRequest req) {
if (req == eMeasRequest.INIT) { // if init, wait until GUI is initialized
synchronized (this) {
while (!initialized) {
System.out.println("I: " + "measThread waits for guiThread to finish initializiation");
try {
wait();
} catch (Exception e) {}
System.out.println("I: " + "measThread awakes");
}
}
}
System.out.println("T: " + "Processing Measurement request: " + req);
// process request here:
sleepMs(5000);
}
});
addGuiRequest(eGuiRequest.INIT);
addMeasRequest(eMeasRequest.INIT);
guiThread.start();
measThread.start();
}
public static void sleepMs(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException ee) {}
}
public static void addGuiRequest(eGuiRequest req) {
guiQueue.add(req);
}
public static void addMeasRequest(eMeasRequest req) {
measQueue.add(req);
}
}