JAVA通信的三种I/O模型

  • BIO(阻塞IO),也就是传统的IO,在进行数据读取时,在数据准备好之前,线程一直挂起,而数据从准备好,需经过硬盘,OS内核(Kernel),JVM,这时一个漫长的过程,但是每一个SOCKET连接,都需要一个线程来监听,对于传输小数据的短连接问题还不大,如果是传输大数据的长连接,那就会有大量线程在系统中,非常浪费内存。
  • java1.4版本出现 NIO(New IO),非阻塞型IO,由SocketChannel来监听所有I/O事件,通常会创建一个java.nio.channels.Selector选择器用来获取SelectionKey,然后根据该Key的事件类型处理,通信方式不再是传统的Socket而是Channel,将连接和读或写的事件,在SocketChannel中注册,事件注册在Kernel(系统内核)中,只有真正事件触发了,才会新建线程去处理返回值,NIO是使用单线程或者只使用少量的多线程,每个连接共用一个线程。线程的利用率提高,他的场景通常是I/O密集,尤其是基于长连接的频繁交互。
  • Java1.7出现AIO,异步IO模型,在NIO的处理方式中,当一个请求来的话,开启线程进行处理,可能会等待后端应用的资源(JDBC连接等),其实这个线程就被阻塞了,当并发上来的话,还是会有BIO一样的问题。AIO中,I/O的事情已经交给内核处理,线程只关注业务,无需等待I/O返回值,AIO相对NIO进一步提升了资源利用率,单这仅仅是相对进程本身而言,整个服务器而言还得看实际情况。这个模型JAVA提供两种机制来实现
    • 第一种是基于回调,实现接口CompletionHandler然后将这个实体传递给相应API,会就在事件触发时自动回调。回调时启用其他线程来处理,可以用线程池。
    • 另一种是返回一个Future,这个Future中有一个方法叫isDone(),若该方法成立,那么数据就准备好了,或者通过get()等待数据完成,显然,isDone()类似于NIO中的线程判定事件,get()类似传统阻塞I/O。它虽然是AIO模型但是并没有达到目的。
  • DirectBuffer:可以直接映射磁盘,跳过内核到JVM的内存拷贝,但是分配内存时,开销巨大,看情况使用,一般创建后尽量重复利用。
  • 在将数据读取到内存时,一定要注意阀值,分两种情况处理,小于阀值的数据直接处理,大于的,每次读取设定的阀值长度数据,分批处理。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值