在讲java nio之前,先讲一下io模型,我也是刚刚在网上看的博客学习的,在这里总结一下,有理解不正确的地方,欢迎指正。
同步,异步,阻塞,非阻塞
首先讲一下我们经常听到的几个名词:同步,异步,阻塞,非阻塞
同步指的是有多个任务的时候,需要一件件的按顺序执行,不能穿插进行。异步就是可用同时进行。
阻塞指的是在做某件事情的时候,发现条件不足,但是线程会一直等待直到满足条件。而非阻塞则是在条件不满足时返回一个标志信息告诉线程条件不满足而不会一直等待。
阻塞IO和非阻塞IO
我们还会听到阻塞IO和非阻塞IO:
当用户线程发起一个IO请求操作(本文以读请求操作为例),内核会去查看要读取的数据是否就绪,对于阻塞IO来说,如果数据没有就绪,则会一直在那等待,直到数据就绪;对于非阻塞IO来说,如果数据没有就绪,则会返回一个标志信息告知用户线程当前要读的数据没有就绪。
海子把IO读操作分为两个部分:
(1)查看数据是否就绪
(2)内核将数据拷贝到用户线程
阻塞和非阻塞指的就是第一个部分--查看数据是否就绪的时候。
同步IO和异步IO:
同步IO即 如果一个线程请求进行IO操作,在IO操作完成之前,该线程会被阻塞;
而异步IO为 如果一个线程请求进行IO操作,IO操作不会导致请求线程被阻塞。
事实上,同步IO和异步IO模型是针对用户线程和内核的交互来说的:
对于同步IO:当用户发出IO请求操作之后,如果数据没有就绪,需要通过用户线程或者内核不断地去轮询数据是否就绪,当数据就绪时,再将数据从内核拷贝到用户线程;
而异步IO:只有IO请求操作的发出是由用户线程来进行的,IO操作的两个阶段都是由内核自动完成,然后发送通知告知用户线程IO操作已经完成。也就是说在异步IO中,不会对用户线程产生任何阻塞。
这是同步IO和异步IO关键区别所在,同步IO和异步IO的关键区别反映在数据拷贝阶段是由用户线程完成还是内核完成。所以说异步IO必须要有操作系统的底层支持。