Netty-NIO线程模型

共 5985字,需浏览 12分钟

 ·

2021-05-14 12:25

点击上方蓝色字体,选择“标星公众号”

优质文章,第一时间送达

IO模型基本说明

IO模型简单的理解:就是用什么样的通道进行数据的发送和接收,很大程度上决定了程序通信的性能。

目前为止java共支持3种网络编程模型:BIO,NIO,AIO:

BIO:

同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

线程模型图

代码实例

/**
 * @Author qrn
 * @Date 2021/5/9 下午9:20
 * @Version 1.0
 * @blog https://blog.csdn.net/qq_41971087
 * 实现一个简单的http服务:
 */
public class HttpServiceTest {

    public static void main(String[] args) throws IOException{
      //创建一个 ServerSocket 绑定8801端口
        ServerSocket serverSocket = new ServerSocket(8801);
        while (true){
            try{
                Socket socket = serverSocket.accept();
                service(socket);
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

  //模拟HTTP报文,输出hell,nio到浏览器
    private static void service(Socket socket){
        try{
            PrintWriter printWriter  = new PrintWriter(socket.getOutputStream(),true);
            printWriter.println("HTTP/1.1 200 OK");
            printWriter.println("Content-Type:text/html;charset=utf-8");
            String body = "hello,nio";
            printWriter.println("Content-Length:" + body.getBytes().length);
            printWriter.println();
            printWriter.write(body);
            printWriter.close();
            socket.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}


服务器通信原理

业务场景:

BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

NIO:

1.同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,

多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

2.使用较少的线程便可以处理许多连接,因此也减少了内存管理和上下文切换所带来开销;

3.当没有 I/O 操作需要处理的时候,线程也可以被用于其他任务。

线程模型图

核心组件:

Selector:

选择器,是 Java 的非阻塞 I/O 实现的关键。它使用了事件通知 API 以确定在一组非阻塞套接字中有哪些已经就绪能够进 行 I/O 相关的操作

Channe:

通道,可以同时进行读写,而流只能读或者只能写,通道可以实现异步读写数据,通道可以从缓冲读数据,也可以写数据到缓冲

通道的目的是确保多线程访问的安全。

Buffer:

缓冲区本质是一个可以读写数据的内存块,‘可以理解为是一个容器对象(数组)

在nio中,Buffer是一个顶层抽像类。

public final Buffer flip() {
        limit = position;
        position = 0;
        mark = -1;
        return this;
    }


flip 读写转换,通过position 属性来达到下标的切换实现,当我们调用get 方法从Buffer中读取数据的时候,position都是加1,一直到

与limit 相等的时候就结束。

代码实例:

Buffer代码小实例:

/**
 * @Author qrn
 * @Date 2021/5/5 下午9:43
 * @Version 1.0
 * @blog https://blog.csdn.net/qq_41971087
 */
public class BasicBuffer {
    public static void main(String[] args) {

        /**
         * 创建一个buff 大小为5
         */
        IntBuffer allocate = IntBuffer.allocate(5);

        for(int i=0;i<allocate.capacity();i++){
            allocate.put(i*2);
        }
        //读写转换
        allocate.flip();

        //循环打印buff的值
        while (allocate.hasRemaining()){
            System.out.println(allocate.get());
        }
    }
}

业务场景:

NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持

AIO:

异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。

描述

异步非阻塞 I/O 模型是一种处理与 I/O 重叠进行的模型。读请求会立即返回,说明 read 请求已经成功发起了。在后台完成读操作时,应用程序然后会执行其他处理操作。当 read 的响应到达时,就会产生一个信号或执行一个基于线程的回调函数来完成这次 I/O 处理过程。

在一个进程中为了执行多个 I/O 请求而对计算操作和 I/O 处理进行重叠处理的能力利用了处理速度与 I/O 速度之间的差异。当一个或多个 I/O 请求挂起时,CPU 可以执行其他任务;或者更为常见的是,在发起其他 I/O 的同时对已经完成的 I/O 进行操作。

业务场景:

AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。





版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:

https://blog.csdn.net/qq_41971087/article/details/116572886







粉丝福利:Java从入门到入土学习路线图

👇👇👇

👆长按上方微信二维码 2 秒


感谢点赞支持下哈 

浏览 23
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报