Java NIO Channel详解:通道与操作系统IO的紧密联系

版权申诉
0 下载量 44 浏览量 更新于2024-08-07 收藏 1.13MB DOC 举报
"Java-NIO中的Channel(通道)是与硬件设备、文件、网络套接字等实体建立的开放连接,允许执行多种I/O操作,如读取和写入。相比传统的Stream,Channel支持异步操作,能同时进行输入和输出,并且通常需要与Buffer配合使用,提供更高的性能。主要的Channel类型包括FileChannel、SocketChannel、ServerSocketChannel和DatagramChannel。随着操作系统的演进,从早期的CPU直接处理IO接口到现在的通道模式,Channel成为操作系统支持的高效IO访问方式之一。在操作系统中,IO控制方式经历了轮询、中断、DMA到通道的历程,其中Channel代表了DMA之后的进一步优化,通过DMA控制器实现数据的快速传输,减轻CPU负担。" Java NIO的Channel(通道)是其非阻塞I/O模型的核心组成部分,与传统的Java IO Stream模型有显著区别。Stream是单向的,要么只用于输入,要么只用于输出,而Channel是双向的,可以同时进行读写操作。此外,Stream不直接支持异步操作,而Channel可以通过选择器(Selector)实现非阻塞的I/O操作,提高并发性能。 FileChannel是Java NIO中用于文件操作的通道,可以通过FileInputStream、FileOutputStream的getChannel方法获取。它支持随机访问文件,提供了映射文件到内存(MappedByteBuffer)的功能,可以实现高效的大数据读写。 对于网络通信,Java NIO提供了SocketChannel和ServerSocketChannel,它们分别对应TCP协议的客户端和服务器端。SocketChannel可以从Socket对象的getChannel方法获取,用于处理客户端的网络连接;ServerSocketChannel可以从ServerSocket的getChannel方法获取,用于监听并接受新的客户端连接。这两种通道都可以进行读写操作,使得网络数据传输更加灵活。 另外,DatagramChannel则对应于UDP协议,支持发送和接收数据报。它可以从DatagramSocket的getChannel方法获取,适合于需要无连接、不可靠传输的场景。 在操作系统层面,传统的IO方式(如中断、DMA)虽然提高了效率,但仍然需要CPU参与数据的传输。而Channel的出现,尤其是配合DMA控制器,使得数据可以直接在设备和内存之间传输,无需CPU介入,从而进一步提升了IO操作的效率。这种方式降低了CPU的负载,尤其在处理大量数据时,性能优势更为明显。 Java NIO Channel是高效、非阻塞的I/O模型的关键,它通过与Buffer的协作以及与操作系统底层的紧密联系,为开发者提供了更强大、更灵活的IO编程能力。理解并熟练使用Channel,对于构建高性能的Java应用具有重要意义。
2023-06-12 上传

2023-07-14 15:19:01.215 WARN 7308 --- [sson-netty-2-15] io.netty.util.concurrent.DefaultPromise : An exception was thrown by org.redisson.misc.RedissonPromise$$Lambda$888/0x00000008008f7440.operationComplete() java.lang.NullPointerException: null 2023-07-14 15:19:01.216 ERROR 7308 --- [sson-netty-2-15] o.r.c.SentinelConnectionManager : Can't execute SENTINEL commands on /172.24.107.11:26379 org.redisson.client.RedisException: ERR No such master with that name. channel: [id: 0x2d66827d, L:/172.23.9.103:46812 - R:/172.24.107.11:26379] command: (SENTINEL SLAVES), params: [mymaster] at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:365) ~[redisson-3.13.3.jar:3.13.3] at org.redisson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:196) ~[redisson-3.13.3.jar:3.13.3] at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:134) ~[redisson-3.13.3.jar:3.13.3] at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:104) ~[redisson-3.13.3.jar:3.13.3] at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:501) ~[netty-codec-4.1.51.Final.jar:4.1.51.Final] at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366) ~[netty-codec-4.1.51.Final.jar:4.1.51.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) ~[netty-codec-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.51.Final.jar:4.1.51.Final] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.51.Final.jar:4.1.51.Final] at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.51.Final.jar:4.1.51.Final] at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na] 解决方法

2023-07-15 上传