如何正确停止等待来自 stdIn 的输入的线程?

Edu*_*edo 5 java concurrency multithreading

我已经实现了一个简单的聊天应用程序,它接收消息并将它们重定向到所有用户,因为我正在学习并行编程。

客户端有两个线程:一个用于侦听服务器,另一个(主线程)用于写入服务器。

这些是用于实现这一点的代码:

主线:

    try {
        Thread listener = new Thread(new Receiver(in));
        listener.start();
        while (listener.isAlive()) {
            out.println(stdIn.readLine());
        }
        out.close();
        in.close();
        clientSocket.close();
    } catch (IOException e) {
        System.err.println("Error trying to send text to server" + e.getMessage());
    }
Run Code Online (Sandbox Code Playgroud)

可用于第二个线程:

public class Receiver implements Runnable {

    private BufferedReader in;

    public Receiver(BufferedReader serverInput) {
        this.in = serverInput;
    }

    @Override
    public void run() {
        String responseLine;
        try {
            while ((responseLine = in.readLine()) != null) {
                System.out.println(responseLine);

                if (responseLine.contains("Bye")) break;
            }
        } catch (IOException e) {
                System.err.println("Erro ao receber mensagem do servidor: " + e.getMessage());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

客户端应该发送一条消息 (#quit) 以退出聊天,服务器将回复一条消息 (Bye) 来完成客户端应用程序。

在接收器线程停止它的生命周期后,如何停止主线程?

我使用该isAlive()方法来完成它,但是在用户发送 #quit 消息之后,线程仍然处于活动状态,并且它再次stdIn.readline()中断线程,直到用户发送另一条消息,即使他已经断开连接。

我尝试实现另一个线程(称为发送方)将消息发送到服务器并listener.join()在主线程上使用 中断发送方线程Thread.interrupt(),但发送方线程仍然落在该stdIn.readline()方法上,我不知道如何正确中断 IO。

如果有人想阅读完整代码,可以在此github 页面中找到

Bis*_*Abd 2

@Override
public void run() {
    String responseLine;
    try {
        while(!isInterrupted()) 
        while ((responseLine = in.readLine()) != null) {
            System.out.println(responseLine);

            if (responseLine.contains("Bye")) break;
        }
    } catch (IOException e) {
            System.err.println("Erro ao receber mensagem do servidor: " + e.getMessage());
    }
}
Run Code Online (Sandbox Code Playgroud)

从另一个线程调用interrupt()该线程以将其关闭

例如,在打印 stdInput 之前检查它是否为“bye”,然后调用中断


您还可以使用类似标志isRunning并调用方法shutdown()

//member variable 
 private static volatile boolean isRunning = true;

public static void shutdown()
    {
        running = false;
    }

    public void run()
    {
        while( running )
        {
            //do whatever.
        }
Run Code Online (Sandbox Code Playgroud)