您的位置 首页 java

AIO搭建聊天室

最近在学习Netty,然后就从 java 传统BIO到NIO然后AIO开始温习了下,目前刚刚到AIO,基于一个学习的结果,想分享下

有需要一起学习的,可以加个关注,嘻嘻

这里是阶段总结中的一部分,在我的微信公众号里,有系列博文,那里可能更全面一些,有需要的朋友,也可以搜索微信公众号“依荨”关注。谢谢

A IO ,一个异步非阻塞的IO操作,其异步相对常规的BIO和NIO的不同在哪儿呢?

以文件复制为例,传统的像这样:

AIO搭建聊天室

基于同步IO的聊天室客户端连接服务端的TCP连接也是像这样:

AIO搭建聊天室

简言之,类似网页前端向服务端发起的AJAX请求,这是个客户端向服务端发送的一个 “同步的Ajax请求”。

那么AIO则提供了一个“异步的Ajax请求”,怎么理解这句话?读写文件或者TCP连接总是立马返回,不会存在同步等待。

这时候,文件复制就像这样了:

AIO搭建聊天室

聊天室的TCP连接就像这样了:

AIO搭建聊天室

下面,以为文件复制为例,简单了解下AIO的异步非阻塞:

AIO搭建聊天室

这里列举了AIO异步读写数据的两种方式,下面对代码做些简单的解释《以下代码行对应上述代码行》:

AIO异步读写文件方式一<java.util.concurrent. Future >,对应上述方法

copyFileAsyncChannelByFuture,即87-126行代码

87-91行:打开读写异步文件通道AsynchronousFileChannel,一个是读,一个是写

93行:分配读写缓冲区

由于这里用较大文件复制作为示例,故没有分配足够大的缓冲区来一次读写完,所以选择循环读写,循环结尾100-124行,表示当文件复制后大小相等则复制完成,退出复制循环。

100行:异步读取文件数据,这个时候,程序立马返回结果,不管是否读取完成。返回对象为java.util.concurrent.Future

102-106行:可以通过java.util.concurrent.Future#isDone判断读取是否完成,如果没有完成,这里仅仅实例打印了一行文字–可以做其他的事,即在实际应用场景中,程序可以在读取文件的同时做其他的任何事,而不是同步阻塞在这里

110行:切换读写模式,变成写

112行-117行:和读取的意义一样,不做过多解释

109行:由于循环读取,这里需要一个参数来分批读取和写入数据

java.nio.channels.AsynchronousFileChannel#read(java.nio.ByteBuffer, long )

java.nio.channels.AsynchronousFileChannel#write(java.nio.ByteBuffer, long)

上述2个方法,需要传入2个参数,

AIO搭建聊天室

第二个参数为读/写的位置,所以119行的参数就是来记录这个位置的

120行:清空缓冲区

最后文件复制完成。

AIO异步读写文件方式二,回调方法处理,对应上述方法copyFileAsyncChannelByCompletionHandler,即31-78行代码

31-35行:打开读写异步文件通道AsynchronousFileChannel,一个是读,一个是写

36行:分配读写缓冲区

39行:定义CountDownLatch,这个是用来让 线程 等待,让其他线程执行完之后再执行的工具类,这里由于AIO读写异步操作,为了展示完整复制文件功能,所以用了这个工具,实际的项目中,除非特定情况,一般来说是不会让线程挂起的,所以这里仅仅为了这里的功能而使用

40-52行:读取文件,由于是异步的,所以在53行执行线程挂起,让读取文件操作完成后,再执行之后的代码。这里的读取文件方式,采用回调方法执行,即

java.nio.channels.CompletionHandler接口

这个接口有2个方法

java.nio.channels.CompletionHandler#completed

表示成功后执行的代码

java.nio.channels.CompletionHandler#failed

表示失败后执行的代码

这种读取方法–>

java.nio.channels.AsynchronousFileChannel#read(

java.nio.ByteBuffer,

long,

A,

java.nio.channels.CompletionHandler<java.lang.Integer,? super A>)

需要传入4个参数:缓冲区,读取起始位置,附加IO操作对象《可以为空》,回调接口

AIO搭建聊天室

53行:线程挂起,直到其他线程结束才能执行之后的代码。这里需要等到读取结束,所以在读取成功后的45行代码,调用java.util.concurrent.CountDownLatch#countDown方法,告诉程序其他线程执行完毕<由于前面初始化CountDownLatch时,指定线程数为1,然后调用countDown减去1,则其他线程为0。即CountDownLatch只要其他线程为0时,当前线程就不再挂起了,继续执行后续程序>

54行:切换读写模式,变成写

56-68行:写入操作同读取,这里不再赘述

69行:记录读写文件位置

73-76行:复制完成,退出循环

下面,基于AIO的异步非阻塞操作,来写下基于AIO的聊天室搭建

服务端:

AIO搭建聊天室

客户端:

AIO搭建聊天室

对于上述代码,这里不做过多解释,每一步操作,基于前面的解释,都是可以理解的。

运行上述代码,简单的聊天室就好了:

AIO搭建聊天室

文章来源:智云一二三科技

文章标题:AIO搭建聊天室

文章地址:https://www.zhihuclub.com/177851.shtml

关于作者: 智云科技

热门文章

网站地图