簡體   English   中英

Java while(true)循環運行一次

[英]Java while(true) loop runs once

我正在編寫一個服務器-多客戶端通信應用程序,並且需要創建一個循環並接受客戶端的Thread 我當前的代碼是:

Thread acceptor = new Thread() {
    public void run() {
        while(true){
            System.out.println("looking for clients");
            try{
                Socket s = serverSocket.accept();
                    clientList.add(new ConnectionToClient(s));
                }
                catch(IOException e){ e.printStackTrace(); }
            }
        }
    }
};
acceptor.setDaemon(true);
acceptor.start();

但是,當我運行應用程序時, looking for clients的文本只會出現一次,並且沒有客戶端可以連接。

我不明白為什么我的while(true)循環實際上沒有循環,只運行了一次。

編輯:

ConnectionToClient構造函數為:

ConnectionToClient(Socket socket) throws IOException {
    this.socket = socket;
    in = new ObjectInputStream(socket.getInputStream());
    out = new ObjectOutputStream(socket.getOutputStream());

    Thread read = new Thread(){
        public void run(){
            while(true){
                try {
                    Object obj = in.readObject();
                    messages.put(obj);
                } catch(IOException | ClassNotFoundException | InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };
    read.start();
 }

您正在調用acceptor.setDaemon(true);

其Javadoc說明:

將此線程標記為守護程序線程或用戶線程。 當僅運行的所有線程都是守護程序線程時,Java虛擬機將退出。

因此,您將唯一正在運行的線程標記為守護程序線程(因為主線程在main方法結束時結束)。 您很幸運,得到了循環的一次迭代,因為沒有更多的非守護線程,您的VM幾乎立即退出了。

解決方案:刪除讀取acceptor.setDaemon(true);


您更新后的帖子顯示了另一個問題,構造函數ConnectionToClient(Socket socket)意外地嘗試從Socket讀取,它會阻塞接收器線程,直到客戶端發送數據為止。

問題是ObjectInputStream的構造方法試圖讀取對象流的標頭。

因此,您應該將ObjectInputStreamObjectOutputStream的構造移到read Thread中,以免阻塞acceptor Thread。

好的,感謝@ErwinBolwidt。

問題是:

1) .setDaemon(true)引起了問題。

2)在連接客戶端之前創建ObjectInputStream的過程是讀取需要發送到服務器的標頭,並阻止客戶端將其發送到服務器。 將其移至讀取線程可以使客戶端實際連接到服務器。

再次感謝@ErwinBolwidt。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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