印象中,我对于NIO的学习,最早是来源于一次面试,面试官问我:“可不可以讲一下Netty的线程模型?”。当然了,这个问题没答上来,于是回去后就开始搜Netty的资料,了解Netty是干什么的,用在哪些场景,Netty的原理和模型是什么…
当我查了大量的博客和文章之后,发现还是很模糊,就像是知道计算机是怎么用的,但是为什么可以这么用,是怎么做到的,还是没有很清晰形象的解释,总是看了就忘,然后再回头来看。于是,就想着从底层去学习下。而Netty是在NIO的基础上实现的网络通信框架,那么就从NIO开始研究吧!
Java NIO( New Input / Output)是Jdk1.4 加入的新特性,最开始是相对于Jdk1.4之前的Java IO(Input / Output)来讲的,是一种新的IO操作方式,于是就有了“NIO”这个名字,当然,后面很多人把它定义为非阻塞式IO(No Bloking IO),具体的定义可以自行查看百科和官方解释。
而要学习Java NIO,还需要一些知识的铺垫,这样能够帮助我们更好的理解它。这是一个开源的世界,为了尊重原创,就不再照搬和重复造轮子,仅整理下个人认为写的比较好的文章推荐给大家,不必再花力气去找资料。
一、UNIX 5种IO模型
《UNIX 5种IO模型,推荐阅读此篇》,我找到的最早的文章是CSDN的一篇博客,叫《UNIX下5种IO模型》,不过简书的那版排版更好一点,也加入了作者自己的一些理解,推荐前一篇。
在此,解释下文章中的几个迷惑知识点:
1. 同步/异步和阻塞/非阻塞:
阻塞/非阻塞,是基于用户线程来定义的;同步/异步,是基于数据Copy来讲的。
阻塞,是指用户线程在发起IO操作请求后,用户线程被挂起,需一直等待数据copy完成后返回。
非阻塞,是指发起IO操作请求后,内核会立马返回收到请求,这个时候用户线程可以去干其他事了,等数据准备完成后,内核会通知用户线程,然后用户线程再发起数据Copy的动作。
同步,是指内核将数据从磁盘Copy到内核空间后,会通知用户线程,然后由用户线程发起请求,从内核空间Copy到用户线程空间。
异步,是指内核将数据从磁盘Copy到内核空间后,不通知用户线程,自动将数据Copy到用户线程空间,然后再通知用户线程,事情已经做完了。
在实际运用中,只存在同步阻塞、同步非阻塞、异步,对于异步来讲,不存在异步阻塞的概念,这只是概念混淆,就好比是,明明可以走直线,非得绕一大圈,没有意义!
在这里,再补充一个概念,《零拷贝》,减少了上下文切换,性能提升很高。
二、Java 多线程
这块要掌握进程、线程、线程池、锁和线程安全相关的知识。
《JVM内存模型》 《Java多线程》 《线程池的使用》 《锁》 《线程安全》
三、Java IO
看了很多文章,推荐一篇写的比较详细的 《Java IO 概述》。
纠正里面一个书写错误,3.5.3部分 FileInputStream(文件 字符 字节流)或FileReader(文件字节字符流)
四、Java NIO
系列篇,接上一篇 《Java NIO详解一》《Java NIO详解二》
后续有新的理解会继续补充,欢迎留言共同学习。