Java NIO(1)概述

来源:互联网 发布:淘宝网生产许可证编号 编辑:程序博客网 时间:2024/05/17 17:55

NIO概述

NIO(Non-blocking I/O,在Java领域,也称为New I/O),是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为解决高并发与大量连接、I/O处理问题的有效方式。

首先我们来看看同步和异步,阻塞与非阻塞的区别
1.同步与异步
同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)
所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由调用者主动等待这个调用的结果。
而异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。

2.阻塞与非阻塞
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.
阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

通俗的例子
同步阻塞:你打电话告诉老板你要买某书,老板拿起电话听你说完就去查书,没有说话,你什么也不知道,在得到任何结果之前,你一直拿着电话干等,你此时什么也干不了。30分钟后老板直接把书送到你家,这时你才挂断电话。每次电话你都要得得到结果(书到家)后你才挂断电话,这是同步。你一直拿着电话等结果,这是阻塞。

同步非阻塞:你打电话告诉老板你要买某书,老板拿起电话后说“我不知道有没有货,现在去查”便挂了电话,又过了10分种你第二次打电话说你要买某书,老板拿起电话说完“还没有查到,你再等会儿”便挂断电话。挂断电话5分钟后老板查到有书,但并没有主动打电话告诉你。你再次等待10分钟后第三次电话老板问结果,老板说“书有了,我给你送到家”,你断挂电话。每次电话你都要得得到结果(去查->还没有查到->有货)后你才挂断电话,这是同步。你每隔10分钟打电话询问结果,这是非阻塞。

异步阻塞:你打电话过去问老板有没有某书,老板说“我不知道有没有货,现在去查,先挂了电话,有结果告诉你,你等我电话”就挂掉电话。等电话期间你什么也不干,老板主动给你发短信通知你结果书有了,5分钟后希望老板现在把书送来,你再次打电话让老板送书,老板马上送书上门。老板主动给你发短信,这是异步。等待老板的短信期间你什么也没干,这是阻塞。

异步非阻塞:你打电话过去后问老板有没有某书,老板说“好的,有货我直接给你送上门”就挂掉电话。然后你想干嘛干嘛,等老板把书送到后你看书。等待老板主动给你送书上门,这是异步。挂了电话后你就想干嘛干嘛,这是非阻塞。

 Java IO : 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
 Java NIO : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

IO与NIO的区别
IO是面向流的,而NIO是面向块的。面向块的方式中,一次性可以获取或者写入一整块数据,而不需要一个字节一个字节的从流中读取。面向块的方式处理数据的速度会比流方式更快。


NIO核心组件

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

 Channels
 Buffers
 Selectors
 
虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Selector 构成了核心的API。其它组件,如Pipe和FileLock,只不过是与三个核心组件共同使用的工具类。

通道 Channel与缓冲器Buffer
Buffer缓冲器是一个保存数据的地方,包括刚刚写入的数据,以及被读取的数据,主要用来追踪系统的读写进程。
Channel与流模式比较类似,但是,永远无法将数据直接写入到Channel或者从Channel中读取数据。需要通过Buffer与Channel交互。基本上,所有的 IO 在NIO 中都从一个Channel 开始。 数据可以从Channel读到Buffer中,也可以从Buffer 写到Channel中。
            这里写图片描述

选择器Selector
Selector 就是您注册对各种 I/O 事件的兴趣的地方,而且当那些事件发生时,就是这个对象告诉您所发生的事件。
Selector允许单线程处理多个 Channel。如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector就会很方便。例如,在一个聊天服务器中。

          这里写图片描述

总结
选择器selector 将 通道channel感兴趣的IO事件注册监听,当其返回时,channel即可对这些IO事件进行处理,一般将这些读写操作都会放到单独的线程中执行,提高吞吐率。

0 0
原创粉丝点击