Java技术教程 – Java中的NIO(非阻塞I/O)详解与案例

2024-12-03 0 162

Java技术教程 – Java中的NIO非阻塞I/O)详解与案例

在Java编程中,I/O操作一直是一个重要的部分,但传统的阻塞I/O模型在处理高并发场景时可能会遇到性能瓶颈。Java NIO(New Input/Output,非阻塞I/O)提供了一种更高效的I/O处理方式,它允许一个线程管理多个输入输出通道,极大地提高了I/O处理的效率。

1. NIO的基本概念

NIO主要由三个核心部分组成:Channel(通道)、Buffer(缓冲区)和Selector(选择器)。

  • Channel:与传统的Stream不同,NIO中的Channel是可以进行读写操作的双向管道。常见的Channel有SocketChannel、ServerSocketChannel、FileChannel等。
  • Buffer:NIO中的所有数据都需要先写入到缓冲区中,然后从缓冲区中获取数据。Buffer提供了对数据的结构化访问。
  • Selector:Selector允许一个线程同时管理多个Channel,通过Selector可以监听多个Channel的事件(如连接、读写),从而大大减少了线程的使用。

2. 简单的NIO示例

下面是一个简单的NIO服务端示例,该示例展示了如何使用NIO来处理客户端的连接和数据读写。

2.1 服务端代码


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NIOServer {
    public static void main(String[] args) throws IOException {
        Selector selector = Selector.open();
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(8080));
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            selector.select();
            Set selectedKeys = selector.selectedKeys();
            Iterator iterator = selectedKeys.iterator();

            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();

                if (key.isAcceptable()) {
                    ServerSocketChannel server = (ServerSocketChannel) key.channel();
                    SocketChannel client = server.accept();
                    client.configureBlocking(false);
                    client.register(selector, SelectionKey.OP_READ);
                } else if (key.isReadable()) {
                    SocketChannel client = (SocketChannel) key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    client.read(buffer);
                    String received = new String(buffer.array()).trim();
                    System.out.println("Received: " + received);
                    buffer.clear();
                    buffer.put(("Echo: " + received).getBytes());
                    buffer.flip();
                    client.write(buffer);
                    client.close();
                }

                iterator.remove();
            }
        }
    }
        

2.2 客户端代码


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class NIOClient {
    public static void main(String[] args) throws IOException {
        InetSocketAddress address = new InetSocketAddress("localhost", 8080);
        SocketChannel socketChannel = SocketChannel.open(address);
        socketChannel.configureBlocking(false);

        String message = "Hello, NIO!";
        ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());
        socketChannel.write(buffer);

        buffer.clear();
        socketChannel.read(buffer);
        String received = new String(buffer.array()).trim();
        System.out.println("Received: " + received);

        socketChannel.close();
    }
}
        

3. 运行示例

先运行服务端代码,然后运行客户端代码。服务端会监听8080端口,当接收到客户端的连接和数据后,会回显收到的数据并关闭连接。

4. 总结

NIO通过非阻塞I/O模型和高效的数据处理方式,提供了比传统阻塞I/O更高的并发性能和更好的资源利用率。通过本教程的学习,你可以掌握NIO的基本概念,并学会编写简单的NIO服务端和客户端程序。

Java技术教程
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

本站尊重知识产权,如知识产权权利人认为平台内容涉嫌侵犯到您的权益,可通过邮件:8990553@qq.com,我们将及时删除文章
本站所有资源仅用于学习及研究使用,请必须在24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担。资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您权益请联系本站删除

腾谷资源站 java Java技术教程 – Java中的NIO(非阻塞I/O)详解与案例 https://www.tenguzhan.com/2234.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务