BIO、NIO、AIO、Netty 学习笔记

BIO、NIO、AIO、Netty 学习笔记_第1张图片 

首先了解一下什么是IO?

Java中I/O是以流为基础进行数据的输入输出的,所有数据被串行化写入输出流。串行化就是数据要按顺序进行输入输出,也就是java通过io流方式和外部设备进行交互。

比如程序从服务器上下载图片,就是通过流的方式从网络上以流的方式到程序中,再到硬盘中。

同步与异步,阻塞与非阻塞的区别

同步,一个任务的完成之前不能做其他操作,必须等待(等于在打电话)。
异步,一个任务的完成之前,可以进行其他操作(等于在聊QQ)。
阻塞,是相对于CPU来说的, 挂起当前线程,不能做其他操作只能等待。
非阻塞,,无须挂起当前线程,可以去执行其他操作。

什么是BIO?

阻塞BIO(blocking I/O)。同步+阻塞,服务器实现一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,没处理完之前此线程不能做其他操作。BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,有一定局限性。

例子:A拿着一支鱼竿在河边钓鱼,并且一直在鱼竿前等,在等的时候不做其他的事情,十分专心。只有鱼上钩的时,才结束掉等的动作,把鱼钓上来。整个过程不能做其他事情

BIO、NIO、AIO、Netty 学习笔记_第2张图片

 

 

什么是NIO?

非阻塞NIO(noblocking I/O)。同步+非阻塞,服务器实现一个连接一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器。

例子:B也在河边钓鱼,但是B不想将自己的所有时间都花费在钓鱼上,在等鱼上钩这个时间段中,B也在做其他的事情(一会看看书,一会读读报纸,一会又去看其他人的钓鱼等),但B在做这些事情的时候,每隔一个固定的时间检查鱼是否上钩。一旦检查到有鱼上钩,就停下手中的事情,把鱼钓上来。 B在检查鱼竿是否有鱼,是一个轮询的过程。

BIO、NIO、AIO、Netty 学习笔记_第3张图片

什么是AIO?

异步AIO(asynchronous I/O)。为了解决NIO不能异步的问题而生的。异步+非阻塞。以异步方式发起 I/O 操作。当 I/O 操作进行时可以去做其他操作,由操作系统内核空间提醒IO操作已完成。

BIO、NIO、AIO、Netty 学习笔记_第4张图片

 什么Netty?

Netty是由JBOSS提供的一个Java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工
具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。Netty 是一个基于NIO的客户、服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。Netty是由NIO演进而来,使用过NIO编程的用户就知道NIO编程非常繁重,Netty是能够能跟好的使用NIO。

BIO和NIO、AIO的区别?

1、IO是阻塞的,NIO是非阻塞的.
2、BIO是面向流的,只能单向读写,NIO是面向缓冲的, 可以双向读写。
使用BIO做Socket连接时,由于单向读写,当没有数据时,会挂起当前线程,阻塞等待,为防止影响其它连接,需要为每个连接新建线程处理,然而系统资源是有限的,不能过多的新建线程,线程过多带来线程上下文的切换,从来带来更大的性能损耗,因此需要使用NIO进行BIO多路复用,使用一个线程来监听所有Socket连接,使用本线程或者其他线程处理连接。
3、AIO是非阻塞 以异步方式发起 I/O 操作。当 I/O 操作进行时可以去做其他操作,由操作系统内核空间提醒IO操作已完成。

什么是内核空间?

应用程序是不能直接访问硬盘的,我们程序没有权限直接访问,但是操作系统会给我们一部分权限较高的内存空间,他叫内核空间,和我们的实际硬盘空间是有区别的。BIO、NIO、AIO、Netty 学习笔记_第5张图片

 Java I/O流的分类

BIO、NIO、AIO、Netty 学习笔记_第6张图片

 按流的方向分类:

  • 输出流:从内存读出到文件。只能进行写操作。
  • 输入流:从文件读入到内存。只能进行读操作。
  • 注意:输出流可以帮助我们创建文件,而输入流不会。

 按处理数据单位大小分类:

  • 字符流 :以字符为单位,每次次读入或读出是16位数据。其只能读取字符类型数据。 (Java代码接收数据为一般为 char数组,也可以是别的 )
  • 字节流:以字节为单位,每次次读入或读出是8位数据。可以读任何类型数据,图片、文件、音乐视频等。 (Java代码接收数据只能为 byte数组 )

按角色分类:

  • 节点流:与硬盘连接,直接与数据源相连,读入或写出。
  • 处理流:与内存连接,也叫包装流,是对一个对于已存在的流的连接进行封装,通过所封装的流的功能调用实现数据读写。如添加个缓冲区。
  • 注意:为什么要有处理流?主要作用是在读入或写出时,对数据进行缓存,以减少I/O的次数,以便下次更好更快的读写文件,才有了处理流。

什么是比特(Bit),什么是字节(Byte),什么是字符(Char),它们长度是多少,各有什么区别?

  • Bit最小的二进制单位 ,是计算机的操作部分取值0或者1。
  • Byte是计算机中存储数据的单元,是一个8位的二进制数(计算机内部,一个字节可表示一个英文字母,两个字节可表示一个汉字。)  取值(-128-127)
  • Char是用户的可读写的最小单位,他只是抽象意义上的一个符号。如‘5’,‘中’,‘¥’ 等等等等。在java里面由16位bit组成Char 取值 (0-65535)
  • Bit 是最小单位 计算机他只能认识0或者1。
  • Byte是8个字节 是给计算机看的。
  • 字符 是看到的东西 一个字符 = 2个字节。

什么叫对象序列化,什么是反序列化,实现对象序列化需要做哪些工作?

  • 对象序列化,将对象以二进制的形式保存在硬盘上
  • 反序列化;将二进制的文件转化为对象读取
  • 实现serializable接口,不想让字段放在硬盘上就加transient。

在实现序列化接口是时候一般要生成一个serialVersionUID字段,它叫做什么,一般有什么用?

  • 如果用户没有自己声明一个serialVersionUID,接口会默认生成一个serialVersionUID
  • 但是强烈建议用户自定义一个serialVersionUID,因为默认的serialVersinUID对于class的细节非常
  • 敏感,反序列化时可能会导致InvalidClassException这个异常。(比如说先进行序列化,然后在反序列化之前修改了类,那么就会报错。因为修改了类,对应的SerialversionUID也变化了,而序列化和反序列化就是通过对比其SerialversionUID来进行的,一旦SerialversionUID不匹配,反序列化就无法成功。

为什么图片、视频、音乐、文件等 都是要字节流来读取?

因为CPU规定了计算机存储文件都是按字节算的。

BIO、NIO、AIO、Netty 学习笔记_第7张图片

  使用NIO实现网络通信

 BIO、NIO、AIO、Netty 学习笔记_第8张图片

 什么是通道(Channel)?

Channel是一个对象,可以通过它读取和写入数据。 也叫做多路复用器,是客户端连接上来的通道。通常我们都是将数据写入包含一个或者多个字节的缓冲区,然后再将缓存区的数据写入到通道中,将数据从通道读入缓冲区,再从缓冲区获取数据。

 什么是选择器(Selector)?

由他选择操作哪个客户端,用户刚刚进来时有个状态,分配好了资源切换状态,完成IO操作是就会变成结束状态。

Selector可以称他为通道的集合,每次客户端来了之后我们会把Channel注册到Selector中并且我们给他一个状态,在用死循环来环判断( 判断是否做完某个操作,完成某个操作后改变不一样的状态 )状态是否发生变化,知道IO操作完成后在退出死循环。

什么是Buffer(缓冲区)?

Buffer 是一个缓冲数据的对象, 它包含一些要写入或者刚读出的数据。

在普通的面向流的 I/O 中,一般将数据直接写入或直接读到 Stream 对象中。当是有了Buffer(缓冲区)后,数据第一步到达的是Buffer(缓冲区)中。

缓冲区实质上是一个数组( 底层完全是数组实现的,感兴趣可以去看一下 )。通常它是一个字节数组,内部维护几个状态变量,可以实现在同一块缓冲区上反复读写(不用清空数据再写)。

你可能感兴趣的:(Java,I/O,BIO,NIO,AIO,netty)