簡體   English   中英

Java:從一個線程到另一個線程的調用方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM