博客
关于我
详细JAVA-NIO介绍与使用
阅读量:311 次
发布时间:2019-03-01

本文共 3311 字,大约阅读时间需要 11 分钟。

Java NIO(非阻塞输入输出)详解

Java NIO(Non-Blocking Input/Output)是Java平台提供的一套用于高效处理输入输出操作的新API,自JDK 1.4起开始提供,旨在替代传统的Blocking I/O(BIO),特别适用于网络编程和文件操作,能够显著提升性能和吞吐量。


Java NIO的核心特点

Java NIO的核心特点在于其非阻塞(Non-Blocking)特性。传统的BIO(Blocking I/O)模式中,IO操作是阻塞的,即一旦等待IO完成,就会阻塞当前线程,无法进行其他操作。而NIO引入了非阻塞模式,通过 Selector(选择器)和 Channel(通道)实现多线程、多任务处理的高效IO操作。

NIO的核心组件包括 Channel(通道)、Buffer(缓冲区)和 Selector(选择器)


NIO与BIO的主要区别

特性 BIO NIO
IO模式 阻塞 非阻塞
数据处理
优点 灵活性不高 灵活性高,支持大规模并发
适用场景 单线程、高负载场景不适合 多线程、高并发场景优选

Buffer(缓冲区)

缓冲区是NIO的核心组件之一,用于临时存储数据块。NIO的缓冲区实现分为多个类型,包括:

  • ByteBuffer:用于存储字节数据。
  • CharBuffer:用于存储字符数据。
  • ShortBuffer、IntBuffer、LongBuffer、DoubleBuffer、FloatBuffer:分别用于存储不同数据类型。

缓冲区提供了灵活的读写操作,支持双向读写(通过 flip() 方法切换读写模式)。


Channel(通道)

通道是NIO中用于读取和写入数据的核心接口。常见的Channel实现包括:

  • FileChannel:用于文件操作。
  • DatagramChannel:用于UDP网络通信。
  • ServerSocketChannelSocketChannel:用于TCP网络通信。

通道支持异步读写操作,数据可以直接从或到缓冲区处理,避免了传统BIO中频繁的数据拷贝,提高了效率。


Selector(选择器)

选择器的作用是管理多个通道的事件处理。一个选择器可以管理多个通道(Channel),通过线程轮询这些通道是否有可读或可写事件发生。一旦有事件发生,选择器会通知相应的通道,进行数据读写操作。

Selector的常用方法包括:

  • open():获取选择器实例。
  • select(long timeout):阻塞或非阻塞地等待事件发生。
  • selectedKeys():获取已触发事件的选择键集合。

NIO非阻塞网络编程流程

服务端流程

  • 创建 ServerSocketChannel 并绑定端口。
  • ServerSocketChannel 注册到选择器,关注连接事件(SelectionKey.OP_ACCEPT)。
  • 进入选择器的阻塞模式,等待客户端连接。
  • 当有连接事件发生时,获取新的 SocketChannel 并将其注册到选择器,关注读写事件。
  • 客户端流程

  • 创建 SocketChannel 并配置非阻塞模式。
  • 连接到服务端地址。
  • 发送数据到服务端,数据通过缓冲区(ByteBuffer)处理。
  • 服务端接收数据,通过选择器分发给相应的通道进行处理。

  • 示例代码

    以下是NIO非阻塞网络编程的典型示例:

    服务端

    public class NIOServer {    public static void main(String[] args) throws Exception {        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();        Selector selector = Selector.open();        InetSocketAddress inetSocketAddress = new InetSocketAddress(6666);        serverSocketChannel.socket().bind(inetSocketAddress);        serverSocketChannel.configureBlocking(false);        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);        while (true) {            int selected = selector.select(1000);            if (selected == 0) {                continue;            }            Set
    selectionKeys = selector.selectedKeys(); Iterator
    keyIterator = selectionKeys.iterator(); while (keyIterator.hasNext()) { SelectionKey selectionKey = keyIterator.next(); if (selectionKey.isAcceptable()) { SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024)); } keyIterator.remove(); } } }}

    客户端

    public class NIOClient {    public static void main(String[] args) throws Exception {        SocketChannel socketChannel = SocketChannel.open();        socketChannel.configureBlocking(false);        InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 6666);        if (!socketChannel.connect(inetSocketAddress)) {            while (!socketChannel.finishConnect()) {                System.out.println("Connecting to server...");            }        }        ByteBuffer buffer = ByteBuffer.wrap("Hello, World!".getBytes());        socketChannel.write(buffer);        System.in.read();    }}

    总结

    Java NIO通过引入非阻塞模型、缓冲区和选择器,显著提升了IO操作的效率,特别适用于高并发和大规模数据处理场景。在实际应用中,NIO的选择器和通道机制能够有效管理多线程和多任务,优化了系统性能。通过合理使用缓冲区和通道,开发者可以实现更高效的数据读写操作。

    转载地址:http://dyxo.baihongyu.com/

    你可能感兴趣的文章
    PHP基于openssl实现的非对称加密操作
    查看>>
    php基本符号大全
    查看>>
    php基础篇-二维数组排序 array_multisort
    查看>>
    php基础配置环境变量
    查看>>
    php增删改查封装方法
    查看>>
    springboot之jar包Linux后台启动部署及滚动日志查看且日志输出至文件保存(超级详细)
    查看>>
    php多条件筛选功能的实现
    查看>>
    php多线程
    查看>>
    PHP大数组循环-避免产生Notice或者是Warning
    查看>>
    PHP大数组过滤元素、修改元素性能分析
    查看>>
    PHP大文件切片下载代码
    查看>>
    PHP如何下载远程文件到指定目录
    查看>>
    php如何优化压缩的图片
    查看>>
    php如何做表格,新手怎么制作表格
    查看>>
    RabbitMQ高级特性
    查看>>
    php如何定义的数位置,php如何实现不借助IDE快速定位行数或者方法定义的文件和位置...
    查看>>
    RabbitMQ集群 - 普通集群搭建、宕机情况
    查看>>
    php如何正确的获得文件的后缀名
    查看>>
    PHP如何生成唯一的数字ID
    查看>>
    PHP如何获取当前页面的最后修改时间
    查看>>