【问题标题】:Is BufferedReader.readLine() over a Socket a blocking operation?Socket 上的 BufferedReader.readLine() 是阻塞操作吗?
【发布时间】:2015-08-18 16:59:57
【问题描述】:

我正在尝试运行一个示例类,该类使用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 块永远不会被执行。

【问题讨论】:

    标签: java sockets stream observable


    【解决方案1】:

    正如BufferedReader.readLine() 状态

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

    只有在另一端关闭连接时,你才会得到null

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

    【讨论】:

    • 好的,谢谢,现在我可以让它以另一种方式工作
    • 代码在哪里?
    • @gumuruh 唯一的代码在 OP 中
    【解决方案2】:

    您不能在套接字周围创建BufferedReader,因为BufferedReader 只是包装了另一个ReaderReaders 根本不支持非阻塞 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,它将继续读取,直到行完成或流到达其末尾,这意味着在阻塞套接字中流已关闭。

    【讨论】:

    • 以你的方式做那件事。我需要做的是在没有输入的情况下通过代码理解
    • 我试图解释的是,使用Readers 或InputStreams 时没有“无输入”条件。它们只支持阻塞 I/O,这意味着等待至少一个 byte/char 可以被读取。对于非阻塞 I/O,您必须直接使用 Channels,但没有与 Reader 等效的非阻塞,因此您必须进行整个字符集转换并手动扫描行尾.提供这样的解决方案将超出 SO 的范围。
    • 好吧抱歉,现在我明白了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-22
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多