[英]Java: Calling method from threads one after another
我有Server類和ClientThread子類。 ClientThread具有方法receive()和broadcast(String [] msg),用於從與服務器連接的客戶端接收和發送消息。
方案:
public class Server extends Thread {
private ArrayList<ClientThread> clientThreads;
class ClientThread extends Thread {
public void broadcast(String[] msg) {...}
public void receive() {
...
if (msg.equals("CHANGED")) {
resumeOthers();
}
public void suspendOthers() {
for (ClientThread c: clientThreads)
if (c!=this)
try {
c.wait();
} catch (InterruptedException e) {}
}
public void resumeOthers() {
for (ClientThread c: clientThreads)
if (c!=this)
c.notify();
}
}
public void run() {
...
cmd = new String[1];
cmd[0] = "PROMPTCHANGE";
for (ClientThread currPlayer: clientThreads) {
currPlayer.broadcast(cmd);
currPlayer.suspendOthers();
}
}
}
現在,我想使此ClientThreads一次接一個地工作,如下所示:
1. ClientThread number 1 is calling method broadcast.
Now any other ClientThread existing is freezed
(they are stored in ArrayList on Server)
2. Client (another class) replies with a message that is being caught by receive()
Now this thread is freezed, and the next one starts running
不幸的是,我的方法行不通。 有人可以詳細解釋一下我該如何實現嗎?
通過調用Object.wait(),您正在掛起CALLING線程,而不是該對象恰巧所在的線程。
因此,實際上,您正在執行一個循環,該循環阻塞了N次調用線程,這絕對不是您想要的。
為了暫停線程,您需要讓IT等待對象,或使其阻塞進入同步塊(或使用Thread.sleep(),但通常不是一個好的解決方案)。 換句話說,客戶端線程需要調用wait,而不是調用線程。
另外一個:似乎您不熟悉Java線程和同步,我強烈建議您在嘗試此操作之前先閱讀一下。
Google到處尋找有關該主題的一些文檔。 以下是一些入門知識: http : //docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
尚不清楚執行順序如何工作。 無論如何,正如前面的答案已經說過的那樣,在Object
上調用x.wait()
會使對象x上的當前線程阻塞。 而且,為了調用wait()
和notify()
,您首先必須在該對象上進行同步,並且,當您調用wait()
,您應該循環執行,檢查外部條件,因為虛假喚醒會發生。
因此,正確的模式應類似於:
void waitForCondition() {
synchronized (lockObject) {
while (!condition) {
lockObject.wait();
}
}
}
void setCondition() {
synchronized (lockObject) {
condition = true;
lockObject.notify(); //or .notifyAll()
}
}
如果要使線程依次運行,請嘗試http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.