BIO就是阻塞的,NIO就是非阻塞?BIO就是堆内存,NIO就是直接内存?用了NIO就高并发,难道是银弹?
NONONO
当然不是!
我们不讲具体技术及名词,存讲概念,把什么是B/NIO理解清楚了,网上的文章太多概念模糊,太千篇一律(也许是我个人一直没怎么深入IO相关开发,最近搞netty,才逐渐将概念清晰,深刻)。
第一,BIO和NIO不是一整套开发技术或者流程,它只是两种IO交互概念
这么说是不是也很笼统,不急,现在就给定义:
- BIO:面向流 Stream(单向读写)
- NIO:面向通道 Channel + 缓冲区 Buffer
嘿,这不是和网上一样吗?没错,再给:
BIO,你就理解,操作系统给你一块内存缓冲,你每次都去查看有没有新数据,有你就搬运,没有你就阻塞等待一会再去查看。
NIO,channel你就理解为句柄和触发器,缓冲区buffer,你就理解为和BIO一样的内存缓冲,它和BIO区别就在于,你不需要主动去查看缓冲,而是触发器触发有数据可以读取了,这就是事件驱动。至于,你的线程要不要等待,还是去做其他事,这就看你想要的了。 回答了开头,NIO既可以是阻塞的,也可以是非阻塞。
第二,内存缓冲 只是块内存,在Java中它没有BIO和NIO之分,只有堆内存还是直接内存的区别。
好理解吧,BIO读取的数据也可以写入直接内存(通过NIO的api),NIO堆内存和直接内存都可以写入,就看你选哪块。
额外强调:现代 JDK(JDK8+)的 DirectByteBuffer 早就做了 JNI 内联优化,老教程吹的「直接内存 JNI 调用慢、频繁用户态内核切换」已经过时了。HotSpot JIT 把直接内存的读写操作内联消除了 JNI 桩,日常读写直接内存几乎没有额外开销,不会频繁切内核。
最后一个问题 NIO就一定快?
不一定哦,看场景,底层基础设施是阻塞的,用了NIO除了IO方式变化了,性能不一定能提升多大,比如数据库,它慢,上层再快有什么用。
而且还有个误区,NIO只是并发能力高了,你底层耗cpu,耗内存等情况,并发能力再高,实际能处理的能力不高,也没用。