Java Bufferedreader阻止线程,但在(br.ready())停止断开连接检查时添加

Java Bufferedreader阻止线程,但在(br.ready())停止断开连接检查时添加,java,multithreading,sockets,bufferedreader,Java,Multithreading,Sockets,Bufferedreader,我正在制作聊天服务器/客户端。我有一个BufferedReader从套接字读取我的inputstream,当它.readLine()时,它会阻塞。我添加了if(BufferedReader.ready()),但这意味着我无法再检测断开连接的客户端,就像我添加了else System.out.println(“客户端断开”)一样,然后每当客户端用户在超过几毫秒的时间内没有发送消息时,它就假定用户断开连接。 我怎样才能摆脱这一切? 代码: } 找到答案问题不在于读取器阻塞了线程,而在于所有代码都是在

我正在制作聊天服务器/客户端。我有一个BufferedReader从套接字读取我的inputstream,当它.readLine()时,它会阻塞。我添加了if(BufferedReader.ready()),但这意味着我无法再检测断开连接的客户端,就像我添加了else System.out.println(“客户端断开”)一样,然后每当客户端用户在超过几毫秒的时间内没有发送消息时,它就假定用户断开连接。 我怎样才能摆脱这一切? 代码:

}

找到答案问题不在于读取器阻塞了线程,而在于所有代码都是在构造函数中编写的,而不是run()方法,因为这意味着另一个线程在继续之前等待构造函数完成

我有一个BufferedReader从套接字读取我的inputstream,当它.readLine()时,它会阻塞

对。这是特定的行为

我添加了if(BufferedReader.ready()),但这意味着我无法再检测断开连接的客户端

对。
ready(),
的正确用法很少,这不是其中之一

然后,每当客户端用户在超过几毫秒的时间内没有发送消息时,它就假定用户已断开连接

这是代码中的一个bug。不要在“几毫秒”后“推测”

我怎样才能摆脱这一切


您正在使用阻塞I/O。您需要指定一个线程来读取套接字,并检测流结束或异常以指示对等断开连接。

问题是,我还有三个其他线程,一个线程是在客户端加入以处理其连接请求时创建的(这反过来会创建此线程)一个用于处理任何新检测到的客户端(这反过来会创建连接请求线程),另一个是用于处理用户输入的主线程(这是新检测到的客户端线程的开始),但是当涉及到
BufferedReader.readLine()
@dodo不,它们不是。只有调用
readLine()
的线程才会阻塞。如果它们都在同一个套接字上调用
readLine()
,则说明您的代码和设计存在严重错误。
import java.io.BufferedReader;
import java.io.InputStream;
import java.net.Socket;

public class SpeechHandler implements Runnable {

public SpeechHandler (BufferedReader r, ServerMain sm, Socket soc) {

    try {

    boolean connected = true;

    while (connected) {

        try {

            String text = null;

            text = r.readLine();

            if (!text.equals(null)) {

                sm.tellAll(text);

            }

        } catch (Exception e) {

            System.out.println("Client " + soc.getInetAddress() + " has disconnected");
            sm.removeStream(soc.getInputStream());
            sm.removeStream(soc.getOutputStream());
            e.printStackTrace();
            connected = false;

        }

    }

    } catch (Exception e) {

        e.printStackTrace();

    }

}

@Override
public void run () {



}