Java while(true)循环运行一次

时间:2016-08-31 02:46:39

标签: java multithreading sockets loops server

我正在编写Server-Multiclient通信应用程序,我需要创建一个循环并接受客户端的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();
 }

2 个答案:

答案 0 :(得分:4)

您正在致电acceptor.setDaemon(true);

Its Javadoc解释说:

  

将此线程标记为守护程序线程   或用户线程。 Java虚拟机仅在退出时退出   运行的线程都是守护线程。

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

解决方案:删除标有acceptor.setDaemon(true);

的行

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

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

因此,您应该将ObjectInputStreamObjectOutputStream的结构移动到read主题中,这样就不会阻止acceptor主题。< / p>

答案 1 :(得分:0)

好的,感谢@ErwinBolwidt。

问题是:

1).setDaemon(true)导致问题。

2)在连接客户端之前创建ObjectInputStream是读取需要发送到服务器的标头,并阻止客户端将其发送到服务器。将其移动到读取线程允许客户端实际连接到服务器。

再次感谢@ErwinBolwidt。