一、 Java NIO 【Netty系列】

目录

 

一、 Java NIO 【Netty系列】

1、NIO概述

2、NIO的三大核心组件


 

一、 Java NIO 【Netty系列】

最近在B站(ps:小破站真不错!!!)学习Netty相关的视频,有了输入当然就要输出啦,不然脑子就堵死了,开个玩笑,要养成记笔记的习惯(ps:因为大佬都是这么说的),所以在这里做一个笔记的记录,有所感,有所悟。想去看视频的,B站链接在文章末供上。

ok,言归正传,在学习Netty之前,我们先了解一下NIO,因为Netty本质是一个NIO框架。

1、NIO概述

Java支持三种网络编程模型I/O模式:BIO(同步阻塞)、NIO(同步非阻塞)、AIO(异步非阻塞)

BIO是同步阻塞的,客户端和服务端进行通信,客户端每一个请求,服务端就启动一个线程进行处理,这样请求多了,就会产生大量线程,可以使用线程池的方式解决创建线程多的问题,但是依然对服务端的资源要求较高。

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

NIO与BIO一个比较重要的不同,是我们使用BIO的时候往往会引入多线程,每个连接一个单独的线程;而NIO则是使用单线程或者只使用少量的多线程,每个连接共用一个线程(有一个多路复用器,把所有连接都注册到多路复用器上,轮询到连接有I/O请求就进行处理)。Java NIO 全称 java non-blocking IO,是指 JDK 提供的新 API。从 JDK1.4 开始,Java 提供了一系列改进的输入/输出的新特性,被统称为 NIO(即 New IO),是同步非阻塞的。这里涉及一个【同步、异步】【阻塞、非阻塞】问题,在这里说明一下。

 

在Unix的IO模型中

1、同步:用户程序要参与把数据拷贝到程序缓冲区

2、异步:用户程序发起IO请求后,不等待数据,同时操作系统内核负责I/O操作把数据从内核拷贝到用户程序的缓冲区后通知应用程序。数据拷贝是由操作系统内核完成,用户程序从一开始就没有等待数据,发起请求后不参与任何IO操作,等内核通知完成。

1、阻塞:用户程序发起IO操作请求后等待数据返回

2、非阻塞:用户程序发起IO操作请求后不等待数据,而是调用会立即返回一个标志信息告知条件不满足,数据未准备好,从而用户请求程序继续执行其它任务。执行完其它任务,用户程序会主动轮询查看IO操作条件是否满足,如果满足,则用户程序亲自参与拷贝数据动作

总结来说,同步和异步的区别就是数据的拷贝是否需要操作系统来完成,阻塞和非阻塞的区别就是发起一个I/O请求后是否有立刻返回一个标志信息而不让请求线程等待。

2、NIO的三大核心组件

Java NIO 由以下几个核心部分组成:

  • Channels(通道)
  • Buffers(缓冲区)
  • Selectors(选择器)

Channel 和 Buffer

所有的 IO 在NIO 中都从一个Channel 开始。Channel 有点像流,不过Channel 是双向的。数据可以从Channel读到Buffer中,也可以从Buffer 写到Channel中。

一、 Java NIO 【Netty系列】

Java NIO中的一些主要Channel的实现:

  • FileChannel

  • DatagramChannel

  • SocketChannel

  • ServerSocketChannel

FileChannel 用于文件的数据读写,DatagramChannel 用于 UDP 的数据读写,ServerSocketChannel 和SocketChannel 用于 TCP 的数据读写。

【ServerSocketChanne 类似 ServerSocket , SocketChannel 类似 Socket】

Java NIO中的一些主要Buffer的实现:

  • ByteBuffer

  • CharBuffer

  • DoubleBuffer

  • FloatBuffer

  • IntBuffer

  • LongBuffer

  • ShortBuffer

NIO 的通道(Channel) 和 流(Stream)的区别:

  • 通道可以同时进行读写,而流只能读或者只能写

  • 通道可以实现异步读写数据

  • 通道可以从缓冲读数据,也可以写数据到缓冲

Selector

Java NIO 引入 Selector ( 选择器 )的概念,它是 Java NIO 得以实现非阻塞 IO 操作的最最最关键。

我们可以注册多个 Channel 到一个 Selector 中。而 Selector 内部的机制,就可以自动的为我们不断的执行查询( select )操作,判断这些注册的 Channel 是否有已就绪的 IO 事件( 例如可读,可写,网络连接已完成 )。

通过这样的机制,一个线程通过使用一个 Selector ,就可以非常简单且高效的来管理多个 Channel 了。

一、 Java NIO 【Netty系列】

 

后续文章会对三个组件详细介绍。

小破站链接:https://www.bilibili.com/video/BV1DJ411m7NR

一起学习,一起进步,加油!!!