Java中网络IO的实现方式(BIO、NIO、AIO)介绍

Java中网络IO的实现方式主要有BIO、NIO、AIO三种。下面分别进行介绍。

BIO

BIO即Blocking IO,阻塞式IO,是一种传输方式。BIO的特点是同步阻塞,也就是说,客户端请求到来后,服务器必须处理完该请求才能执行下一步操作,高并发下无法满足需求。使用BIO方式,可以使用SocketServerSocket类进行通信。

下面是一个BIO的示例,该示例利用BIO模拟了一个简单的服务器。

public class SocketHandler extends Thread {
    private InputStream inputStream;
    private OutputStream outputStream;

    public SocketHandler(Socket socket) throws IOException {
        inputStream = socket.getInputStream();
        outputStream = socket.getOutputStream();
    }

    @Override
    public void run() {
        try {
            byte[] buffer = new byte[1024];
            int len = 0;
            if ((len = inputStream.read(buffer)) != -1) {
                String request = new String(buffer, 0, len);
                String response = "response to " + request;
                outputStream.write(response.getBytes());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

public class Server {
    public void start() throws IOException {
        ServerSocket serverSocket = new ServerSocket(8899);
        while (true) {
            Socket socket = serverSocket.accept();
            SocketHandler socketHandler = new SocketHandler(socket);
            socketHandler.start();
        }
    }

    public static void main(String[] args) throws IOException {
        Server server = new Server();
        server.start();
    }
}

NIO

NIO即New IO,新IO,是JDK的1.4版本中引入的新特性。相对于BIO的同步阻塞,NIO采用事件驱动机制,利用轮询的方式进行事件的处理,因此可以更好地支持高并发。使用NIO方式,可以使用ChannelSelector类进行通信。

下面是一个NIO的示例,该示例利用NIO模拟了一个简单的服务器。

public class SocketHandler implements Runnable {
    private SocketChannel socketChannel;
    private Selector selector;
    private ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

    public SocketHandler(SocketChannel socketChannel, Selector selector) throws IOException {
        this.socketChannel = socketChannel;
        this.selector = selector;
    }

    @Override
    public void run() {
        try {
            while (true) {
                int readyChannels = selector.select();
                if (readyChannels == 0) continue;
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                while (iterator.hasNext()) {
                    SelectionKey selectionKey = iterator.next();
                    if (selectionKey.isReadable()) {
                        byteBuffer.clear();
                        socketChannel.read(byteBuffer);
                        byteBuffer.flip();
                        String request = new String(byteBuffer.array(), 0, byteBuffer.limit());
                        String response = "response to " + request;
                        socketChannel.write(ByteBuffer.wrap(response.getBytes()));
                    }
                    iterator.remove();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                socketChannel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

public class Server {
    public void start() throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress(8899));
        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        while (true) {
            int readyChannels = selector.select();
            if (readyChannels == 0) continue;
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                if (selectionKey.isAcceptable()) {
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ);
                } else if (selectionKey.isReadable()) {
                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                    new Thread(new SocketHandler(socketChannel, selector)).start();
                }
                iterator.remove();
            }
        }
    }

    public static void main(String[] args) throws IOException {
        Server server = new Server();
        server.start();
    }
}

AIO

AIO即Asynchronous IO,异步IO,在JDK的1.7版本中引入。相对于NIO的轮询方式,AIO采用异步回调的方式进行事件的处理,更加符合面向对象的思想。使用AIO方式,可以使用AsynchronousServerSocketChannelCompletionHandler类进行通信。

下面是一个AIO的示例,该示例利用AIO模拟了一个简单的服务器。

public class SocketHandler implements CompletionHandler<AsynchronousSocketChannel, Object> {
    private AsynchronousServerSocketChannel serverSocketChannel;

    public SocketHandler(AsynchronousServerSocketChannel serverSocketChannel) {
        this.serverSocketChannel = serverSocketChannel;
    }

    @Override
    public void completed(AsynchronousSocketChannel socketChannel, Object attachment) {
        try {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            socketChannel.read(buffer, attachment, new CompletionHandler<Integer, Object>() {
                @Override
                public void completed(Integer result, Object attachment) {
                    try {
                        buffer.flip();
                        String request = new String(buffer.array(), 0, buffer.limit());
                        String response = "response to " + request;
                        socketChannel.write(ByteBuffer.wrap(response.getBytes()));
                        buffer.clear();
                        socketChannel.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void failed(Throwable exc, Object attachment) {
                    exc.printStackTrace();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            serverSocketChannel.accept(attachment, this);
        }
    }

    @Override
    public void failed(Throwable exc, Object attachment) {
        exc.printStackTrace();
    }
}

public class Server {
    public void start() throws Exception {
        AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(8899));
        serverSocketChannel.accept(null, new SocketHandler(serverSocketChannel));
        System.in.read();
    }

    public static void main(String[] args) throws Exception {
        Server server = new Server();
        server.start();
    }
}

以上就是Java中网络IO的实现方式,包括BIO、NIO、AIO三种,分别适用于不同的场景。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中网络IO的实现方式(BIO、NIO、AIO)介绍 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • java模仿windows计算器示例

    下面我将为您详细讲解如何使用Java语言模仿Windows计算器,并提供两个示例说明。步骤如下: 第一步:创建基本的计算器界面 在Java中,可以使用Swing框架来实现窗口界面设计。首先需要使用JFrame类创建一个窗口,然后在窗口中添加各种控件(按钮、文本框、标签等)。 在创建窗口之前,需要导入Swing框架中的各种类和方法。代码示例: import j…

    Java 2023年6月15日
    00
  • Java十道入门易踩坑题分析后篇

    Java十道入门易踩坑题分析后篇 1. 理解Java中的基本数据类型 在Java中,基本数据类型包括整型、字符型、布尔型、浮点型和字节型。其中,整型包括byte、short、int和long四种类型;浮点型包括float和double两种类型;字符型只有char一种类型;布尔型只有boolean一种类型。 在使用基本数据类型时需要注意以下几点:- 整型的范围…

    Java 2023年5月23日
    00
  • 详解json在SpringBoot中的格式转换

    下面详细讲解“详解json在SpringBoot中的格式转换”的完整攻略。 什么是JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,通常用于前后端数据交互。它基于JavaScript语言中的对象字面量表示法,而且易于读写和解析生成,被广泛应用于Web开发中。 JSON实际上就是一个字符串,它使用键值对的方式…

    Java 2023年5月26日
    00
  • java 字符串匹配函数

    Java 字符串匹配函数指的是在字符串中查找特定子串出现的位置或数量的函数。在 Java 中,有多种实现字符串匹配的函数,其中最常用的是 String 类的相关方法以及正则表达式。 下面是 Java 字符串匹配的完整攻略: 使用 String 方法进行字符串匹配 Java 提供了一系列的 String 方法,支持在字符串中查找特定子串出现的位置或数量。这些方…

    Java 2023年5月26日
    00
  • Springboot的maven间接依赖的实现

    下面就来详细讲解一下Springboot的maven间接依赖的实现。 首先,我们需要理解一下什么是maven依赖。在项目中,我们常常需要引入不同的jar包来实现不同的功能,而这些jar包之间可能存在依赖关系。如果我们手动去下载并放置这些jar包,并且手动管理它们之间的依赖关系,就会非常繁琐和复杂。Maven就是一个依赖管理工具,它通过定义pom.xml文件来…

    Java 2023年5月20日
    00
  • java 两个数组合并的几种方法

    Java两个数组合并的几种方法 介绍 在Java中,有时候需要将两个数组合并成一个数组。本文将介绍Java中合并两个数组的几种方法。 方法一:使用for循环 首先,我们可以使用for循环来合并两个数组。具体的操作是,将第一个数组的元素复制到新的数组中,然后将第二个数组的元素复制到新的数组中。 示例代码: public static int[] mergeAr…

    Java 2023年5月27日
    00
  • JDK8 中Arrays.sort() 排序方法详解

    JDK8 中 Arrays.sort() 排序方法详解 简介 Arrays.sort() 是 Java 中用于对数组进行排序的方法之一。该方法可用于对数字数组进行快速排序,也可用于对字符串数组进行字典序排序等。本文将详细讲解 JDK8 中 Arrays.sort() 排序方法的使用,包括参数、返回值、排序算法等。 方法参数 Arrays.sort() 方法有…

    Java 2023年5月26日
    00
  • 一文详解Java闭锁和栅栏的实现

    一文详解Java闭锁和栅栏的实现 1. 什么是闭锁和栅栏 在并发编程中,有时需要等待某个操作的完成,或者协调多个线程的执行。Java提供了闭锁(Latch)和栅栏(Barrier)两个机制来实现这种协调。 闭锁是一种同步工具,可以使线程等待一个或多个线程的操作完成。闭锁一般会在某个线程等待另一个线程完成任务时使用。 栅栏是一种同步工具,它允许一组线程在某个点…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部