IO(BIO)和NIO的区别:其本质就是阻塞和非阻塞的区别。

  阻塞概念:应用程序在获取网络数据的时候,如果网络传输数据很慢,那么程序就一直等着,直到传输完毕为止。

  非阻塞概念:应用程序直接可以获取已经准备就许好的数据,无需等待。

  IO为同步阻塞形式,NIO为同步非阻塞形式。NIO并没有实现异步,在JDK1.7只后,升级了NIO库包,支持异步非阻塞通信模型即NIO2.0(AIO)

同步和异步:同步和异步一般是面向操作系统与应用程序对IO操作的层面上来区别的。

  同步时,应用程序会直接参与IO读写操作,并且我们的应用程序会直接阻塞到某一方法上,直到数据准备就绪:或者采用轮询的策略实时检查数据的就绪状态,如果就绪则获取数据。

  异步时,则所有的IO读写操作交给操作系统处理,与我们的应用程序没有直接关系,我们程序不需要关心IO读写,当操作系统完成了IO读写操作时,会给我们应用程序发送通知,我们的应用程序直接拿走数据即可。

同步说的是你的server服务端的执行方式

阻塞说的时具体的技术,接收数据的方式,状态(io,nio)

  

NIO编程介绍

学习NIO编程,要先了解几个概念:

Buffer(缓冲区)、Channel(管道、通道)、Selector(选择器,多路复用器)

 Bufer:

buffer是一个对象,它包含一些要写入或者要读取的数据。在NIO类库中假如Buffer对象,体现了新库与原IO的一个重要的区别。在面向流的IO中,可以将数据直接写入或读取到Stream对象中。在NIO库中,所有数据都是用缓冲区处理的(读写)。缓冲区实质上是一个数组,通常它时一个字节数组(ByteBuffer),也可以使用其他类型的数组。这个数组为缓冲区提供了数据的访问读写等操作属性,如位置、容量、上限等概念,具体参考API文档。

Buffer类型:我们最常用的就是ByteBuffer,实际上每一种java基本类型都对于了一种缓存区(除了Boolean类型):

ByteBuffer   CharBuffer  ShortBuffer  IntBuffer  LongBuffer  FloatBuffer  DoubleBuffer

下面看一下IntBuffer的使用:

在put完数据后,一定要调用flip()方法,使position位置复位,然后才能通过遍历把每个数据取出来,其他的都可以看注释看清楚。

下面我们看一下打印结果:

可以清楚的看到buf里面的各个阶段的属性。下面看一下warp方法的使用

先看一下打印的结果:

然后在看一下jdk的api文档:

http://tool.oschina.net/apidocs/apidoc?api=jdk-zh

应该就能看的懂了。

下面看一下其他的方法:

看一下打印结果:

可以看的出来buf的方法都不太好用,但是Netty框架里面,对这个buffer做了很多的封装,使得Netty的buffer非常好用。

注意:在JDK的api中,在buf中放入数据后,一定要检查position的位置,在复位后,才能调用数据去获取buffer的内容。

下面看一下Channel

Channel,它就像自来水的管道一样,网络数据通过Channel读取和写入,通道与流不同支出在与通道是双向的,而流只是一个方向上移动(一个流必须是InputStream或者OutputStream的子类),而通道可以用于读、写或者二者同时进行,最关键的是可以与多路复用器结合起来,有多种的状态位,方便多路复用器去识别。事实上通道分为两大类,一类是网络读写的(SelectableChannel),一类是用于文件操作的(FileChannel),我们使用的SocketChannel和ServerSocketChannel都是SelectableChannel的子类。

再看一下Selector

多路复用器(Selector),他是NIO编程的基础,非常重要。多路复用器提供选择已经就绪的任务的能力。

简单说,就是Selector会不断的轮询注册在其上的通道(Channel),如果某个通道发生了读写操作,这个通道就处于就绪状态,会被Selector轮询出来,然后通过SelectionKey可以取得就绪的Channel集合,从而进行后续的IO操作。

一个多路复用器(Selector)可以负责成千上万的Channel通道,没有上线,这也是JDK使用了epoll代替了传统的select实现,获得连接句柄没有限制。这也就意味着我们只要一个线程负责Sekector的轮询,就可以接入成千上万个客户端,这是JDK NIO库的巨大进步。

Selector线程就类似一个管理者(Master),管理了成千上万和管道,然后轮询那个管道的数据已经准备好,通知cpu执行IO的读取或写入操作。

Selector模式:当IO事件(管道)注册到选择器之后,selector会分配给每个管道一个key值,相当于标签。selector选择器是以轮询的方式进行查找注册的所有IO事件(管道),当我们的IO事件(管道)准备就绪后,select就会识别,会通过key值来找到相应的管道,进行相关的数据处理操作(从管理里读或写数据,写到我们的数据缓冲区中)。

每个管道都会对选择器进行注册不同的事件状态,以便选择器查找。

  SelectionKey.OP_CONNECT

  SelectionKey.OP_ACCEPT

  SelectionKey.OP_READ

  SelectionKey.OP_WRITE

下面看一个实例:

先看一端server端的代码:

先解读一下上面的代码,先看一下run方法,在这个方法中,selector复用器去轮询注册在上面的通道的key,轮询的不只是ServerSocketChannel,还注册在上面的SockerChannel,在最开始,selector上肯定只有一个ServerSocketChannel,此时,这个通道肯定是处于阻塞状态的,这个时候调用accept方法,去监听接入的SockerChannel通道,如果没有接入,就一直处于阻塞状态,如果有SocketChannel接入,就把SocketChannel注册到selector上,然后因为run方法是无限循环的,在遍历到SocketChannel通道时,检测到状态是可读状态,就开始执行read方法,读取客户端传递过来的消息。并打印一下结果。

下面看一下Client的代码:

客户端的代码比较简单,就是从键盘接收数据,然后传输给客户端。上面这种实现只是客户端给服务端发送数据。

NIO和IO(BIO)的区别及NIO编程介绍的更多相关文章

  1. Java NIO 与 IO之间的区别

    概述 Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲 ...

  2. Java NIO系列教程(十一) Java NIO 与 IO

    Java NIO系列教程(十一) Java NIO与IO 当学习了 Java NIO 和 IO 的 API 后,一个问题马上涌入脑海: 我应该何时使用 IO,何时使用 NIO 呢?在本文中,我会尽量清 ...

  3. Java NIO学习系列四:NIO和IO对比

    前面的一些文章中我总结了一些Java IO和NIO相关的主要知识点,也是管中窥豹,IO类库已经功能很强大了,但是Java 为什么又要引入NIO,这是我一直不是很清楚的?前面也只是简单提及了一下:因为性 ...

  4. Java之NIO与IO比较分析

    Java NIO(New Input/Output)——新的输入/输出API包——是2002年引入到J2SE 1.4里的.Java NIO的目标是提高Java平台上的I/O密集型任务的性能. 简单描述 ...

  5. Java提供了哪些IO方式?IO, BIO, NIO, AIO是什么?

    IO一直是软件开发中的核心部分之一,而随着互联网技术的提高,IO的重要性也越来越重.纵观开发界,能够巧妙运用IO,不但对于公司,而且对于开发人员都非常的重要.Java的IO机制也是一直在不断的完善,以 ...

  6. Java NIO与IO的区别和比较

    传统的socket IO中,需要为每个连接创建一个线程,当并发的连接数量非常巨大时,线程所占用的栈内存和CPU线程切换的开销将非常巨大.使用NIO,不再需要为每个线程创建单独的线程,可以用一个含有限数 ...

  7. Java NIO 和 IO 的区别详解

    Java NIO为jdk1.4提供了新的API,本文主要来比较一下Java中NIO和IO的区别,Java初学者可以了解一下. 下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部分 ...

  8. Java中NIO和IO区别和适用场景

    NIO是为了弥补IO操作的不足而诞生的,NIO的一些新特性有:非阻塞I/O,选择器,缓冲以及管道.管道(Channel),缓冲(Buffer) ,选择器( Selector)是其主要特征. 概念解释: ...

  9. 二十四、JAVA的NIO和IO的区别

    一.JAVA的NIO和IO 1.NIO:面向缓冲区(buffer)(分为非阻塞模式IO和阻塞模式IO)组成部分:Channels管道,Buffers缓冲区,Selectors选择器 2.IO:面向流( ...

随机推荐

  1. PowerDesigner 把Comment写到name中 和把name写到Comment中 pd7以后版本可用

    在使用PowerDesigner对数据库进行概念模型和物理模型设计时,一般在NAME或Comment中写中文,在Code中写英文.Name用来显 示,Code在代码中使用,但Comment中的文字会保 ...

  2. nginx 配置文件配置

    server { listen 80 ; server_name test.com www.test.com; index index.html index.php index.htm; root / ...

  3. CSS样式学习-2

    一.大小 ①width宽:height高. !注释:<a><span>无法使用该方法调整大小 控制元素的大小:宽高.下例是宽高分别100像素的div标签. <div st ...

  4. 机器学习进阶-图像形态学变化-礼帽与黑帽 1.cv2.TOPHAT(礼帽-原始图片-开运算后图片) 2.cv2.BLACKHAT(黑帽 闭运算-原始图片)

    1.op = cv2.TOPHAT  礼帽:原始图片-开运算后的图片 2. op=cv2.BLACKHAT 黑帽: 闭运算后的图片-原始图片 礼帽:表示的是原始图像-开运算(先腐蚀再膨胀)以后的图像 ...

  5. EmEditor

    姓 名:ttrar.com 序 列 号:DKAZQ-R9TYP-5SM2A-9Z8KD-3E2RK 免费版地址:https://zh-cn.emeditor.com/#download

  6. WDA-5-VIEW视图切换

    这一部分介绍同一窗口下不同视图之间的链接跳转. 前提:完成上一步骤MAIN视图ALV显示. 1.效果展示 点击ALV物料下划线链接,页面跳转到物料明细页面. 2.实现过程 基于上一步骤在MAIN页面显 ...

  7. js 选项卡制作

    知识回顾,制作JS选项卡,仅供参考 html代码: <!DOCTYPE html> <html lang="en"> <head> <me ...

  8. 用Hadoop AVRO进行大量小文件的处理(转)

    使用 使用使用 使用 HDFS 保存大量小文件的缺点:1.Hadoop NameNode 在内存中保存所有文件的“元信息”数据.据统计,每一个文件需要消耗 NameNode600 字节内存.如果需要保 ...

  9. Haskell语言学习笔记(70)NonEmpty

    NonEmpty(非空列表) infixr 5 :| data NonEmpty a = a :| [a] deriving (Eq, Ord) instance Functor NonEmpty w ...

  10. mycat的schema.xml的个人的一点理解

    官方文档里讲的详细的部分的我就不再赘述了,我只是谈谈我自己的理解 刚开始接触mycat,最重要的几个配置文件有server.xml,schema.xml,还有个rule.xml配置文件 具体都是干啥用 ...