Java NIO学习

JavaNIO

关于缓冲和阻塞

内核缓冲与进程缓冲区

用户程序进行IO的读写,基本上会用到read&write两大系统调用。

read系统调用,并不是把数据直接从物理设备,读数据到内存。write系统调用,也不是直接把数据,写入到物理设备。

read系统调用,是把数据从内核缓冲区复制到进程缓冲区;而write系统调用,是把数据从进程缓冲区复制到内核缓冲区。等待缓冲区达到一定数量的时候,再进行IO的调用,提升性能。至于什么时候读取和存储则由内核来决定,用户程序不需要关心。这个两个系统调用,都不负责数据在内核缓冲区和磁盘之间的交换。底层的读写交换,是由操作系统kernel内核完成的。

在linux系统中,系统内核也有个缓冲区叫做内核缓冲区。每个进程有自己独立的缓冲区,叫做进程缓冲区。所以,用户程序的IO读写程序,大多数情况下,并没有进行实际的IO操作,而是在读写自己的进程缓冲区。

在这里插入图片描述

首先看看一个典型Java 服务端处理网络请求的典型过程:

(1)客户端请求

Linux通过网卡,读取客户端的请求数据,将数据读取到内核缓冲区。

(2)获取请求数据

服务器从内核缓冲区读取数据到Java进程缓冲区。

(1)服务器端业务处理

Java服务端在自己的用户空间中,处理客户端的请求。

(2)服务器端返回数据

Java服务端已构建好的响应,从用户缓冲区写入系统缓冲区。

(3)发送给客户端

Linux内核通过网络 I/O ,将内核缓冲区中的数据,写入网卡,网卡通过底层的通讯协议,会将数据发送给目标客户端。

阻塞与非阻塞

阻塞IO,指的是需要内核IO操作彻底完成后,才返回到用户空间,执行用户的操作。阻塞指的是用户空间程序的执行状态,用户空间程序需等到IO操作彻底完成。传统的IO模型都是同步阻塞IO。在java中,默认创建的socket都是阻塞的。

非阻塞IO,指的是用户程序不需要等待内核IO操作完成后,内核立即返回给用户一个状态值,用户空间无需等到内核的IO操作彻底完成,可以立即返回用户空间,执行用户的操作,处于非阻塞的状态。

简单的说:阻塞是指用户空间(调用线程)一直在等待,而且别的事情什么都不做;非阻塞是指用户空间(调用线程)拿到状态就返回,IO操作可以干就干,不可以干,就去干的事情。

关于NIO

NIO主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector。传统IO基于字节流和字符流进行操作,而NIO基于Channel和Buffer(缓冲区)进行操作。

NIO和传统IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。面向流意味着每次需要读取所有的字节,它们没有被缓存在任何地方,它不能前后移动流中的数据。

NIO的缓冲导向方法是将数据读取到一个缓冲区,需要时可在缓冲区中前后移动,这就增加了处理过程中的灵活性。但是,需要检查该缓冲区中包含的数据是否正确和完整(TCP粘包和拆包)。数据不完整需更多的数据读入缓冲区时,注意不要覆盖缓冲区里尚未处理的数据。

IO的各种流是阻塞的。当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被完全读取,或数据完全写入。该线程在此期间不能再干任何事情了。

NIO的非阻塞读,使一个线程从某通道读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。调用方法之后会立即返回,而不是保持线程阻塞。非阻塞写也是如此,一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。

Buffer的使用:buffer的几个标志状态如下

在这里插入图片描述
在这里插入图片描述

几个重要方法:

ByteBuffer.flip():position设回0,limit设成之前的position的值

ByteBuffer.clear():position将被设回0,limit设置成capacity

ByteBuffer.compact():将所有未读的数据拷贝到Buffer起始处,然后将position设到最后一个未读元素正后面,limit设置成capacity。

Buffer.mark():可以标记Buffer中的一个特定的position

Buffer.rewind():将position设回0,可以重读Buffer中的所有数据。limit保持不变,表示能从Buffer中读取多少个元素。

关于Reactor模式

待续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值