Java while(true) 循环运行一次

Cam*_*ole -1 java sockets multithreading loops server

我正在编写一个服务器-多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();
Run Code Online (Sandbox Code Playgroud)

但是,当我运行我的应用程序时,文本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();
 }
Run Code Online (Sandbox Code Playgroud)

Erw*_*idt 5

你在打电话acceptor.setDaemon(true);

它的 Javadoc解释说:

将此线程标记为守护线程或用户线程。当唯一运行的线程都是守护线程时,Java 虚拟机退出。

因此,您将唯一正在运行的线程标记为守护线程(因为您的主线程在main方法结束时结束)。你很幸运,你得到了一次循环迭代,因为你的虚拟机几乎立即退出,因为没有更多的非守护线程。

解决方案:删除读取的行 acceptor.setDaemon(true);


您更新的帖子显示了另一个问题,构造函数ConnectionToClient(Socket socket)无意中尝试从 读取Socket,这会阻止接受器线程,直到客户端发送数据。

问题是ObjectInputStream尝试读取对象流的标头的构造函数。

为此,你应该将的建设ObjectInputStreamObjectOutputStreamread主题,所以这不会阻止acceptor线程。