写在前面
阻塞是阻塞, 阻塞(一定要等到读写至少一个字节), 非阻塞(立刻返回即使没有读写到内容返回0)
异步是异步, file(交给一个线程池去做异步阻塞读取) socket(channel 注册到一个epoll实例,由事件驱动,selector线程池处理事件并写Future或者callback)
------------------------------------------
先讲一下阻塞和非阻塞IO吧。
java的IO接口中只有 SelectableChannel 定义了configureBlocking方法,这个方法的实现在AbstractSelectableChannel这个类中,
而这个类的子类只有一些TCP,UDP,SCTP相关实现()(图1)。会发现没有FileChannel
从下图(图二)中也可以发现FileChannel没有实现AbstractSelectableChannel
为什么 FileChannel不用实现非阻塞IO 呢?可以参考 https://www.remlab.net/op/nonblock.shtml
A FileChannel
cannot be set into non-blocking mode. It always runs in blocking mode.
这里提取两段比较重要的内容
----------------------------------------------------------------------------------------------
再来看看Linux 下 AsynchronousSocketChannel和 AsynchronousFileChannel 如何实现异步的。
AsynchronousSocketChannel
首先设置Channel 被设置为非阻塞
在读的时候如果socket 的recive buffer 里面没有内容直接返回 UNAVAILABLE,
将一个event 注册到一个port实例上, 这个port 实例包含了一个Epoll 实例。而有一个线程池在轮询这个Epoll实例上已经准备好的Event.
-----------------------------AsynchronousFileChannel
AsynchronousFileChannel 的实现比较简单,因为File Channel没有非阻塞的实现,所以其不能使用Epoll相关的特性实现异步,所以其仅仅简单地通过一个线程池去做异步的事情。
本文只是简单地描述一下相关的实现。以便以后自己复习。