当前位置: 首页 > 后端技术 > Java

java—water—NIO和AIO

时间:2023-04-01 14:34:00 Java

I,阻塞IO到一个新的连接,新开一个线程处理,后面的所有操作都由这个线程完成。性能瓶颈:1、每个线程都需要一部分内存,消耗得很快。同时,线程切换的开销非常大。2.阻塞操作也是一个问题。首先,accept()是一个阻塞操作。创建新线程后,并不意味着对方会传输数据。所以,SocketChannel#read方法会阻塞,等待数据,显然这种等待是不值得的。同样,write方法也需要等待channel可写后再执行写操作,这里的阻塞等待是不值得的。二。非阻塞IO非阻塞IO的核心是使用一个Selector来管理多个通道,可以是SocketChannel或者ServerSocketChannel,将每个通道注册到Selector中,并指定监听的事件。之后只能用一个线程轮询Selector,看看上面是否有channel准备好了。当通道准备好可读或可写时,才可以开始真正的读写,速度非常快。NIO中的Selector是对底层操作系统实现的抽象。管理通道的状态实际上是由底层系统实现的。这里简单介绍下不同系统下的实现。select:1980年代实现的,支持注册FD_SETSIZE(1024)套接字,那时候肯定够了,现在不行了。poll:1997年,poll作为select的替代品出现。最大的不同是poll不再限制socket数量。epoll:2002年随Linux内核2.5.44发布,epoll可以直接返回具体准备好的通道,时间复杂度为O(1)。select和poll都有一个共同的问题,就是只会告诉你准备了多少个channel,而不会告诉你有哪些channel。因此,一旦您知道有通道准备就绪,您仍然需要执行扫描。显然,这不是很好。频道少的时候还可以。一旦通道数超过几十万,一次扫描的时间就相当可观了。是的,时间复杂度是O(n)。因此,后来又诞生了epoll。三、异步IOJava异步IO提供了两种使用方式:返回Future实例future.isDone();判断操作是否已经完成,包括正常完成、异常抛出、取消future.cancel(true);取消操作的方式是中断。参数true表示即使任务正在执行,也会被中断。未来.isCancelled();无论取消与否,该方法都会返回truefuture.get();仅当任务在任务正常结束前被取消;获取执行结果并阻塞。future.get(10,TimeUnit.SECONDS);带有超时块的get()方法。使用回调函数CompletionHandlercompleted(Vresult,Aattachment);是否完成失败(Throwableexc,Aattachment);是否失败