Java 如何正确停止正在等待stdIn输入的线程?

Java 如何正确停止正在等待stdIn输入的线程?,java,multithreading,concurrency,Java,Multithreading,Concurrency,我已经实现了一个简单的聊天应用程序,它接收消息并将它们重定向到所有用户,因为我正在学习并行编程 客户端有两个线程:一个用于侦听服务器,另一个(主线程)用于写入服务器 以下是用于实现此目的的代码: 主线程: try { Thread listener = new Thread(new Receiver(in)); listener.start(); while (listener.isAlive()) { out.pr

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

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

以下是用于实现此目的的代码:

主线程:

    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());
    }
可运行第二个线程:

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());
        }
    }
}
客户端应该发送一条消息(#quit)以退出聊天,服务器将向其发送一条消息(Bye)以完成客户端应用程序

接收方线程停止其生命周期后,如何停止主线程?

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

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

如果有人想阅读完整的代码,可以在这里找到

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

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


您还可以使用像
isRunning
这样的标志,并调用方法
shutdown()


这个问题没有简单的解决方案,因为从流中读取是一个阻塞操作,我在EHCache/Terracotta中看到的一个技巧是使用2个线程而不是1个线程,一个线程将实际读取流(可调用),而另一个线程将设置一个执行器服务并提交第一个线程(任务)(使用)


这有一个详细的描述

谢谢你的回答。我已经尝试从另一个线程调用
interrupt()
方法,但是主线程仍然在
readline()
上等待输入,即使在调用interrupt之后也是如此。基本上,用户仍然需要在退出前发送最后一条无用的消息。标志解决方案借助于
Thread.sleep()
工作,该解决方案将一直休眠到服务器响应,如果线程被中断,将引发异常。但我想这很容易出错。
@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());
    }
}
//member variable 
 private static volatile boolean isRunning = true;

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

    public void run()
    {
        while( running )
        {
            //do whatever.
        }