BufferedReader.readLine()是否通过Socket进行阻塞操作?

时间:2015-08-18 16:59:58

标签: java sockets stream observable

我试图运行一个使用Observer接口和Observable子类的示例类来检查来自套接字的输入流何时与空字符串不同。这是代码(Observable类):

@Override
public void run() {
    String input;
    while (true) {
        try {
            input = reader.readLine();
            if (input != null) {
                setChanged();
                notifyObservers(input);
            } else
                System.out.println("Nothing read from the stream");
        } catch (IOException e) {
        }
    }
}

因此,当条件input != null为真时,调用update()方法并将其输出到已从套接字读取的stdout。服务器每秒发送一个字符串,观察者以最大速度检查它(没有任何sleep()个调用)。那么,从套接字拥有的流中读取时,BufferedReader.readLine()真正做了什么?因为永远不会执行else块。

2 个答案:

答案 0 :(得分:1)

作为BufferedReader.readLine()

  

包含行内容的字符串,不包括任何行终止字符;如果已到达流的末尾,则为null

当另一端关闭连接时,您将只获得null

如果你想实现繁忙的等待策略,你可以使用非阻塞的NIO,但要注意这将使用100%的一个CPU。

答案 1 :(得分:1)

您无法在套接字周围创建BufferedReader,因为BufferedReader只包含另一个ReaderReader根本不支持非阻塞I / O.

在创建BufferedReader之前,您必须创建Reader

Channels.newReader(…)

  

...如果要读取字节时通道处于非阻塞模式,则会抛出IllegalBlockingModeException

如果您尝试the detour via an InputStream, e.g. acquired by Socket.getInputStream(),也会发生类似情况:

  

如果频道处于非阻塞模式,则输入流的读取操作将抛出IllegalBlockingModeException

因此,只有当套接字处于阻塞模式时才能使用BufferedReader.readLine(),这意味着它将等待至少一个字符被读取,这是一个与流结束不同的条件。因此,作为Peter Lawrey pointed out,它将继续读取,直到该行完成或流到达其结束,这意味着在阻塞套接字中该流已被关闭。