請與我裸露我還是很新的線程...簡單的一種方式暫停線程
我有一個小項目,我有2個線程ListenerThread
和HeartbeatThread
這是內部HeartbeatServer
兩個嵌套類。
我有什麼是監聽線程增加了客戶registerClients
當有人發送一個請求(剩下的就是出這個問題的範圍)。
我正在尋找一種簡單的方法來暫停HeartbeatThread
,當registerClients
散列映射中沒有客戶端時。
本來我想它會爲使用if語句在ListenerThread
while循環,檢查有多少客戶有,如果客戶端計數小於零ListenerThread
稱之爲heartbeatServer.heartbeatThread.wait()
和頂部那樣容易當客戶端數量大約爲零時爲heartbeatServer.heartbeatThread.notify()
。但是,當我這樣做時,java會拋出一個IllegalMonitorException
。在做了一些挖掘之後,我發現這個例外是因爲我沒有在塊內調用wait()
。
因爲我只想去一個方向ListenerThread -> HeartbeatThread
並從來沒有任何其他方式我怎麼能做到這一點?在每個線程中使用塊還是會更好。如果是這種情況,那麼我需要澄清我正在同步的是什麼。
我發現這個例子;
boolean ready = false;
// thread 1
synchronized(lock) {
ready = true;
lock.notifyAll();
}
// thread 2
synchronized(lock) {
while(!ready)
lock.wait();
}
這個例子看起來像它會解決我的問題。但由於我是新手,我不確定lock
應該是什麼。
能否例如返工或完成適合我的需要,還是有更好的方法來解決我的問題?
我真的不知道什麼代碼將需要表演,所以我可以張貼要求的事情。
UPDATE
我想,我終於想出了一個解決我的問題。 公共類HeartbeatServer {
final Object lock = new Object();
volatile Boolean suspended = true;
//TEST USE ONLY
volatile int userCount = 0;
// This is the thread that will send the heartbeats back to the client.
private class HeartbeatThread implements Runnable {
@Override
public void run() {
HeartbeatServer heartbeatServer = HeartbeatServer.getInstance();
while (true) {
synchronized (heartbeatServer.lock) {
if(suspended) {
try {
System.out.println("Suspending heartbeat thread!");
heartbeatServer.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println("Resuming heartbeat thread!");
} // End if block
} // End synchronized block
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
} // End while loop
} // End run method
} // End HeartbeatThread
// This is the thread that will listen for clients connecting to the server.
private class ListenerThread implements Runnable {
// The instance of heartbeatServer should be the first object so we can use it everywhere in the class.
HeartbeatServer heartbeatServer = HeartbeatServer.getInstance();
private void suspendHeartbeats() {
synchronized (heartbeatServer.lock) {
heartbeatServer.suspended = true;
}
} // End suspendHeartbeats
private void resumeHeartbeats() {
synchronized (heartbeatServer.lock) {
heartbeatServer.suspended = false;
heartbeatServer.lock.notify();
}
} // End resumeHeartbeats
@Override
public void run() {
while(true) {
if(heartbeatServer.userCount < 1) {
suspendHeartbeats();
} else {
resumeHeartbeats();
}
} // End while loop
} // End run method
} // End ListenerThread
} // End HeartbeatServer
還有什麼我可以做,以提高我的主題? HeartbeatThread中的一些部分從測試中遺留下來。但我更多地提到用於暫停HeartbeatThread的邏輯。
'lock'可以是任何私人對象。你希望它是私有的,所以其他類不能通過自己同步來干擾你的代碼。實際上,'private static final Object lock = new Object();'通常是一個好習慣。 – VGR
所以'lock'只是兩個線程同步的東西?因此,如果我想暫停'HeartbeatThread',我仍然會像以前那樣調用heartbeatServer.heartbeatThread.wait(),但是隻需在'synchronized'的''synchronized'內爲'lock'指定一個虛擬對象?是正確的嗎? – ianc1215
我建議使用java.util.concurrent.locks.ReentrantLock,因爲它是內置java鎖的更現代和理智的選擇。對於正在學習的人來說,它應該更容易理解 – kan