首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >readline()函数的阻塞机制最新版最全详解

readline()函数的阻塞机制最新版最全详解

作者头像
用户7557625
发布2020-07-15 10:17:06
1.1K0
发布2020-07-15 10:17:06
举报

最近在工作中遇到了一个Android的ANR问题,经过分析是WiFiStateMachine调用了系统函数readline(),然后出现了阻塞的现象,然后就深入了解了一下readline函数。网上搜了一下,发现关于readline()函数的解释大都是说readline()函数是阻塞函数,没有消息是并不会返回null,而是一直阻塞在那。至于阻塞的实质,都没有涉及,我经过仔细分析源码,得出结论如下:

我们先看readline函数源码,其中fill()函数才是真正读取数据的地方,只有读取完成之后,才会执行下面“/n”“/r”的判断,而读取数据的时候为什么阻塞,之前并没有人探究,那我们后面看看fill函数。

String readLine(boolean ignoreLF) throws IOException {
        StringBuffer s = null;
        int startChar;

        synchronized (lock) {
            ensureOpen();
            boolean omitLF = ignoreLF || skipLF;

        bufferLoop:
            for (;;) {

                if (nextChar >= nChars)
                    fill();  //真正读取数据的地方
                if (nextChar >= nChars) { /* EOF */
                    if (s != null && s.length() > 0)
                        return s.toString();
                    else
                        return null;
                }
              ...........其他
              charLoop:
                for (i = nextChar; i < nChars; i++) {
                    c = cb[i];
                    if ((c == '\n') || (c == '\r')) {  //判断是否遇到\n或者\r,如果遇到就结束,作为一行数据输出。
                        eol = true;
                        break charLoop;
                    }
                }

fill()函数中,可以看到读取数据是用了read(char[] cbuf, int off, int len) 来读取数据,当没有数据时,n值为0,while循环就不会结束,就会一直在此阻塞。

    private void fill() throws IOException {
        int dst;
        if (markedChar <= UNMARKED) {
            /* No mark */
            dst = 0;
        } else {
        ..............其他
        int n;
        do {
            n = in.read(cb, dst, cb.length - dst);
        } while (n == 0);   //阻塞的关键
        if (n > 0) {
            nChars = dst + n;
            nextChar = dst;
        }
    }

总结: 1、读入的数据要注意有/r或/n或/r/n 2、没有数据时会阻塞,在数据流异常或断开时才会返回null 3、readline()函数不会边读边输出,而是有一个缓冲区,读出的数据先放到缓冲区,遇到/r或/n或/r/n后再输出。

源码路径:xref: /libcore/ojluni/src/main/java/java/io/BufferedReader.java

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-06-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档