Java中I/O是以流为基础进行数据的输入输出的,所有数据被串行化写入输出流。串行化就是数据要按顺序进行输入输出,也就是java通过io流方式和外部设备进行交互。
比如程序从服务器上下载图片,就是通过流的方式从网络上以流的方式到程序中,再到硬盘中。
同步,一个任务的完成之前不能做其他操作,必须等待(等于在打电话)。
异步,一个任务的完成之前,可以进行其他操作(等于在聊QQ)。
阻塞,是相对于CPU来说的, 挂起当前线程,不能做其他操作只能等待。
非阻塞,,无须挂起当前线程,可以去执行其他操作。
阻塞BIO(blocking I/O)。同步+阻塞,服务器实现一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,没处理完之前此线程不能做其他操作。BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,有一定局限性。
例子:A拿着一支鱼竿在河边钓鱼,并且一直在鱼竿前等,在等的时候不做其他的事情,十分专心。只有鱼上钩的时,才结束掉等的动作,把鱼钓上来。整个过程不能做其他事情。
非阻塞NIO(noblocking I/O)。同步+非阻塞,服务器实现一个连接一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器。
例子:B也在河边钓鱼,但是B不想将自己的所有时间都花费在钓鱼上,在等鱼上钩这个时间段中,B也在做其他的事情(一会看看书,一会读读报纸,一会又去看其他人的钓鱼等),但B在做这些事情的时候,每隔一个固定的时间检查鱼是否上钩。一旦检查到有鱼上钩,就停下手中的事情,把鱼钓上来。 B在检查鱼竿是否有鱼,是一个轮询的过程。
异步AIO(asynchronous I/O)。为了解决NIO不能异步的问题而生的。异步+非阻塞。以异步方式发起 I/O 操作。当 I/O 操作进行时可以去做其他操作,由操作系统内核空间提醒IO操作已完成。
Netty是由JBOSS提供的一个Java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工
具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。Netty 是一个基于NIO的客户、服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。Netty是由NIO演进而来,使用过NIO编程的用户就知道NIO编程非常繁重,Netty是能够能跟好的使用NIO。
1、IO是阻塞的,NIO是非阻塞的.
2、BIO是面向流的,只能单向读写,NIO是面向缓冲的, 可以双向读写。
使用BIO做Socket连接时,由于单向读写,当没有数据时,会挂起当前线程,阻塞等待,为防止影响其它连接,需要为每个连接新建线程处理,然而系统资源是有限的,不能过多的新建线程,线程过多带来线程上下文的切换,从来带来更大的性能损耗,因此需要使用NIO进行BIO多路复用,使用一个线程来监听所有Socket连接,使用本线程或者其他线程处理连接。
3、AIO是非阻塞 以异步方式发起 I/O 操作。当 I/O 操作进行时可以去做其他操作,由操作系统内核空间提醒IO操作已完成。
应用程序是不能直接访问硬盘的,我们程序没有权限直接访问,但是操作系统会给我们一部分权限较高的内存空间,他叫内核空间,和我们的实际硬盘空间是有区别的。
因为CPU规定了计算机存储文件都是按字节算的。
Channel是一个对象,可以通过它读取和写入数据。 也叫做多路复用器,是客户端连接上来的通道。通常我们都是将数据写入包含一个或者多个字节的缓冲区,然后再将缓存区的数据写入到通道中,将数据从通道读入缓冲区,再从缓冲区获取数据。
由他选择操作哪个客户端,用户刚刚进来时有个状态,分配好了资源切换状态,完成IO操作是就会变成结束状态。
Selector可以称他为通道的集合,每次客户端来了之后我们会把Channel注册到Selector中并且我们给他一个状态,在用死循环来环判断( 判断是否做完某个操作,完成某个操作后改变不一样的状态 )状态是否发生变化,知道IO操作完成后在退出死循环。
Buffer 是一个缓冲数据的对象, 它包含一些要写入或者刚读出的数据。
在普通的面向流的 I/O 中,一般将数据直接写入或直接读到 Stream 对象中。当是有了Buffer(缓冲区)后,数据第一步到达的是Buffer(缓冲区)中。
缓冲区实质上是一个数组( 底层完全是数组实现的,感兴趣可以去看一下 )。通常它是一个字节数组,内部维护几个状态变量,可以实现在同一块缓冲区上反复读写(不用清空数据再写)。