Java IO

Java IO

牛客的课,整理笔记
在这里插入图片描述

Netty是java领域IO的框架,如果我们要做的是客户端,自己解决通信问题,那么一般都不会用java的IO流,或者用NIO的API去写,因为要解决网络问题会有很多流量问题,安全性,稳定问题去解决,Netty已经帮我们解决好了,所以一般会选用Netty
Netty的地位和Spring的地位是一样的,如果要做web项目的后台,那么用spring,如果做网络编程、IO的一个项目,Netty是不二选择

我们要从这两本书中找到JavaIO存在的缺陷,以及如何解决

在这里插入图片描述

Unix IO模型

Java的IO存在缺陷,需要先了解Unix的IO模型一共有哪些策略,而Java在这基础上实现了哪些策略
在这里插入图片描述

在这里插入图片描述

补充

百度百科
1.阻塞和非阻塞:
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态。
阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

2.同步和异步
同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)。
所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。
换句话说,就是由调用者主动等待这个调用的结果。
而异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。

阻塞IO模型

在这里插入图片描述

第一段将数据拷贝到内核缓冲区,第二个阶段拷贝到用户缓冲区,在这个过程中进程一直是被阻塞的,此模型性能比较差
在这里插入图片描述

非阻塞IO模型

在这里插入图片描述

如果内核缓冲区没有准备好,那么返回一个错误,然后轮询,一直检查这个状态,如果准备好了,返回了一个待调用的状态,那么就把数据拷贝到用户缓冲区,这时就能把数据返回
这个过程中,前一阶段没有阻塞,后一阶段阻塞了。但是性能还是不好的,因为需要轮询,CPU在这个过程中一直在轮询,也不能做其他事,和阻塞基本没什么区别
在这里插入图片描述

IO复用模型

select/poll 虽然也会导致进程阻塞,但是阻塞前已经将多个文件描述符传给了select
在这里插入图片描述

第二阶段recvfrom和阻塞式IO模型一样,但是第一阶段虽然说select也会引起阻塞,但是select会监控多个文件描述符,recvfrom只能处理一个文件描述符,它的处理能力更强
在这里插入图片描述

信号驱动IO模型

在这里插入图片描述

虽然说这种模型看起来更好,但是它的性能并不一定好过IO复用,因为IO复用能扫描多个文件描述符,再用epoll优化以后性能非常好,一个线程就能处理多个调用的访问,处理能力强。而这个模型,一个线程只能处理一个文件描述符,要处理多个用户的访问,需要多个线程,线程数不一样
在这里插入图片描述

异步IO模型

这个是比较理想的模型,但是并不是每个操作系统都支持这个模型
在这里插入图片描述
在这里插入图片描述

五种模型比较

只有第五种是异步的,前四种是同步的;
前四种都有阻塞,所以是同步的,只不过阻塞的阶段不同
在这里插入图片描述

IO多路复用

用一个线程解决并发的问题
在这里插入图片描述
在这里插入图片描述

Java IO模型

javaIO分为三部分,第一部分,传统认知的IO流,BIO;第二部分,NIO,第三AIO,或者叫NIO2
在这里插入图片描述

传统的IO模型,BIO,B是blocking,阻塞的意思
在这里插入图片描述

红色称之为基础流、低级流,直接访问要访问的设备,比如文件数组,接入的是访问的目标
蓝色,高级流,不能接入到目标中去,接入的是一个低级流,
低级流虽然能接到目标上,但是效率比较低,处理比较繁琐;如果用高级流进一步处理低级流,就会变方便
往往是先实例化一个高级流,然后接入一个低级流,通过低级流接到设备中去,处理数据
在这里插入图片描述

之前Java提供的IO流完全和操作系统不匹配,导致效率低下
Buffer对应用户缓冲区,这样面向对象编程很自然,结合了操作系统的体系,
Channel是用户和缓冲区之间的通道,数据读写通过通道来解决,是双向的,不向之前的流只能读或者写

N的意思是new,或者说是No-blocking

如果要用Selector,意味着要解决网络IO的问题,网络IO不建议直接用NIO的方法,更建议用Netty
在这里插入图片描述

在这里插入图片描述

最常用的是ByteBuffer
后者分配的是操作系统的内存
在这里插入图片描述

在这里插入图片描述

初始化,Buffer被实例化,Buffer的最大容量是8,capacity和limit将指向第8个位置的下一个位置

flip在写入数据后使用,表示将position指针重置到头部,limit置于数据区的下一个位置
当调用clear的时候,其实buffer中的数据没有清空,而只是将指针还原,下次写入直接覆盖数据,效率高
在这里插入图片描述

在这里插入图片描述

Channel是一个接口
SocketChannel作为客户端访问通道,ServerSocketChannel作为服务端访问通道
前两类用的比较多

实例化方法不建议使用第二种

map方法是将channel和buffer关联
在这里插入图片描述

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

selectNow不会引起阻塞,会立刻返回的,但是一般没有必要,因为只有一个线程被阻塞;

在这里插入图片描述

NIO2(AIO)
在这里插入图片描述

要用到异步通信的时候,往往是解决网络通信的问题,往往是做网络编程。
所以需要用到AsynchronousServerSocketChannel
在这里插入图片描述

第一个方法返回Future,意思是当调用以后想接入客户端的通道上去,从客户端接收或者发送数据的话,利用Future的get方法,但是这个方法会阻塞线程。调用了accept()这个方法没有阻塞,但是要得到数据还得调用get,还是会阻塞

第二个方法,handler其实就是回调处理函数。这个方法是注册了一个handler,如果数据准备好以后会自动调用handler让调用者去处理,这个方法是不阻塞的。
一般建议使用第二个方法
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值