通用技术 小学生写代码之读取数组

bauul · 2017年08月22日 · 最后由 bauul 回复于 2017年08月24日 · 1246 次阅读

代码

/**
 * Tells whether there are any elements between the current position and
 * the limit.
 *
 * @return  <tt>true</tt> if, and only if, there is at least one element
 *          remaining in this buffer
 */

public final boolean hasRemaining() {
    return position < limit;
}

final char[] hb;                  // Non-null only for heap buffers
protected int ix(int i) { //java.nio.HeapCharBuffer
    return i + offset;
}

public char get() {
    return hb[ix(nextGetIndex())];
}


/**
 * Returns the number of elements between the current position and the
 * limit.
 *
 * @return  The number of elements remaining in this buffer
 */
public final int remaining() {
    return limit - position;
}
for (int i=0; buffer.hasRemaining(), i++) {
  myByteArray[i] = buffer.get();
}
int count = buffer.remaining();
for (int i=0; i<count , i++) {
  myByteArray[i] = buffer.get();
}

我的理解

以前总觉得是第二段 for 循环的代码好,因为它没有重复计算 buffer.remaining()
现在才知道原来还有另一个角度,当使用多线程时,就是第一段的性能更快了。
另外增加了 hasRemaining,get 方法的源码,然后因为第二段 for 循环的终止条件是固定值,所以它是单线程跑的,
但是第一段的 for 循环的终止值是每次算出来的,所以可以多线程调用。

参考

java+NIO 中文版

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 9 条回复 时间 点赞

第一段性能更快的原因是内存操作少?

陈恒捷 回复

不是,是在并发的时候,不过它不是线程安全的,还得加锁

bauul 回复

我的疑问是为啥第一段会更快。貌似文中没说明具体原因。

我更新了一下我的理解,感谢你的疑问👀

陈恒捷 回复

第一段快的唯一原因是……编译器编译不通过,不用执行了😂

哎,看来对 NIO 理解的不透彻啊,再好好看看吧。

hasRemaining 返回一个布尔值,判断 limit 在哪,好从 position 到 limit 之间读取数据。
position 是当前 buffer 的位置,limit 初始值等于 cpacity。
读取进入通道之后 position 等于 0, limit 等于 position,避免越界。

Buffer 确实是非线程安全的,所以要保证数据同步,你需要自己做同步(外部同步,悲观所、乐观锁,重入锁啥的)。
Buffer.remaining() 和 Buffer.hasRemaining() 是一样的。
在用法上没有区别。
Buffer.remaining() 返回剩余可取元素的个数,Buffer.hasRemaining() 判断是否还有,这个函数仅仅是判断是否还有可取的元素,用来做某些判断的场景。

在 for 循环编码优化上,第二段性能更高。第一段每次会对函数进行调用。

多线程上,两者没有区别,第一种并没有提高效率,取决于你自己如何同步的。

另外第一段代码帮你更正一下:
for (int i = 0; i < hasRemaining(); i++) 改成 for (int i = 0; hasRemaining(); i++)

卡农Lucas 回复

嗯啊,为了学习 reactor 模式去了解一下 nio 的

8楼 已删除
卡农Lucas 回复

完全同意你的看法

bauul #10 · 2017年08月24日 Author
卡农Lucas 回复

非常感谢

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册