繁体   English   中英

Writer 线程不会停止,因为 BufferedReader 即使在套接字关闭后也不会关闭

[英]Writer thread doesn't stop because BufferedReader won't close even after socket closure

为什么clientInputReader没有关闭? 此处可用的isReady() 解决方案无法修复它。 我也尝试了 Scanner 而不是 BufferedReader 并遇到了同样的问题。

isDisconnected变量是同一个 class 中的一个实例字段,它同时具有readFromServer()writeToServer()方法。 在没有clientInputReader.close()语句的情况下,readFromServer() 中启动的线程在服务器向其发送“关闭”消息时成功停止,然后它将 isDisconnected 变量设置为 true,但 writeToServer 启动的线程永远不会停止,因为缓冲阅读器不会关闭。

    private volatile boolean isDisconnected;
    private final BufferedReader clientInputReader = new BufferedReader(new InputStreamReader(System.in));
    private void readFromServer() {
        Runnable r = () -> {
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String inputLine;
                while (!Objects.equals(inputLine = in.readLine(), "close")) {
                    System.out.println(inputLine);
                }
                //TODO: Remove
                isDisconnected = true;
                System.out.println("Disconnected");
                in.close();
                System.out.println("Closed input buffer");
                socket.close();
                System.out.println("Closed Socket");
                clientInputReader.close();
                System.out.println("Closed client input reader buffer");

                System.out.println("Closed Connections");
            } catch (IOException e) {
                System.out.println(e.getMessage());
                e.printStackTrace();
            } finally {

            }
        };
        new Thread(r).start();
    }

    private void writeToServer() {
        Runnable r = () -> {
            try {
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                // for reading input on terminal
                String inputLine;
                while (!isDisconnected) {
                    if (clientInputReader.ready()) {
                        while ((inputLine = clientInputReader.readLine()) != null) {
                            out.println(inputLine);
                        }
                    }
                }
                // TODO REMOVE
                System.out.println("Disconnected");
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // TODO REMOVE
                System.out.println("Disconnected Finally");
            }
        };
        new Thread(r).start();
    }

Output:

在此处输入图像描述

(最后一行 - Ctrl C 终止进程)

我当前的解决方案:将编写器线程设置为守护进程。

最后,除了从阅读器线程中杀死编写器线程以结束客户端程序之外,还有什么替代方法?

您可以更改发件人以检查“关闭”,而不是在线程之间使用标志通知。 在双方都使用 try-with-resources 处理,通信变得更加简单且无错误:

// writeToServer: exits loop and closes the stream when "close" is typed
try(PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
    // for reading input on terminal
    String inputLine;
    while (!Objects.equals(inputLine = clientInputReader.readLine(), "close")) {
        out.println(inputLine);
    }
}

// readFromServer - consumes the stream until it it closed:
try(BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
    String inputLine;
    while ((inputLine = in.readLine()) != null) {
        System.out.println(inputLine);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM