NIO 解析

1、传统IO,他是面向流的模式、阻塞式(read() 或write()时线程被阻塞,直到读完)
2、NIO 面向缓冲区(Buffer)、非阻塞、selector
面向缓冲区:可以对缓冲区中的数据进行灵活的操作,可以向前向后操作缓冲区里面的数据(而流只能按照读取流的顺序来操作)变得灵活,以空间换灵活。
非阻塞:其实这就是采用reactor 模式的好处。reactor pattern和observer pattern两种模式类似, 区别在于前者与多个事件源关联, 后者与单个事件源关联. 这点区别, 又反过来印证了上述思想, reactor pattern和多个事件源关联, 每个事件的处理时间很短, 所以, 大家复用线程, 避免线程切换/同步/数据移动带来的性能问题


image.png

NIO 一些基本知识:

  • Channel
  • Buffer
  • Selector

所有的NIO 都是从Channel 开始,channel 和buffer之间可以互相读写,一般用户不直接操作 往channel 里面些数据,而是从buffer里面把数据写入channel;或者 读取数据也一般是从channel里面写入buffer,然后在从buffer在读取。

Selector :允许单线程处理多个channel,Selector 是一个中间管理者,负责channel的注册,根据不同的方式(读写)选择不同的server 或者 回传。
Channel :channel 和流类似,但又不同,流是单向的,通道是双向的。Channel的数据总先从buffer 中读取,或者保存到buffer中。

image.png

主要包括 :

DatagramChannel ==》UDP 读写网络数据
ServerSocketChannel ===》监听新连接,每一个请求都创建一个链接,像Http一样
SocketChannel ===》TCP 请求
SourceChannel、SinkChannel ==》pip
Buffer :Buffer 用于和Channel 交互,数据是从channel 读取入buffer,从buffer写入channel。buffer本质是一块可以写入数据,并且读取的内存。

有3个数据很重要:
Capacity:
缓存区的最大容量,分配空间。你只能往里写capacity个byte、long,char等类型

limit: 是 index
position: index
这两个取决当前是读模式还是写模式。
如果是写模式: position 表示当前写的 位置,limit 最多能写入多少数据,和capacity值一样。
如果是读模式:切换到指定位置, position=0,从该区开始读取,limit 表示已经写入的数据大小

flip()方法
flip方法将Buffer从写模式切换到读模式。调用flip()方法会将position设回0,并将limit设置成之前position的值。(把position设置为0)

Buffer 类型:

byteBuffer,charBuffer,shortBuffer,intBuffer,longBuffer,floatBuffer,longBuffer,MappedByteBuffer
先进行分配
往Buffer 写数据 两种方法:
1、int bytesize= fileChannel.read(buf);
2、通过put:
buf.put(112);
buffer 里面读数据 2种方法
1、int bytewittern=fileChannel.write(buf);//把buffer的数据写到channel中
2、buf.get();
rewind(): 重置读取的位置,limit 不变。

clear()与compact()方法
Clear() ==>进行 缓冲区的标志位重置,position =0,limit =capacity,mark=-1;
compat()==>定位到缓冲区 剩余数据 尾部,后面需要写入数据,接着位置写进去。 Position 保持之前的 位置,limit=capacity,mark=-1;

mark()与reset()方法
标识一个position,然后中途可以做一些事情, 需要回到标示的地方,reset()

equals()与compareTo()方法
Equals :标示缓冲区里面的剩余数据是否相等,跟缓冲区的capacity 无关。
CompareTo: 比较equals,如果equals:(结果< 比较者) 1、看第一个字母<第二个;2、比较buffer 比第二个先耗尽.

Channel 支持 Scatter/gather

Scatter channel 可以把数据写入到不同的buffer中.
原理是,把数据依次写到buffer中,当前buffer写满了,往下一个buffer写数据。

image.png

ByteBuffer headBuf=ByteBuffer.allocate(180);
ByteBuffer bodyBuf=ByteBuffer.allocate(1024);
ByteBuffer[] bufferArray = { header, body };
channel.read(bufferArray);

Scattering Reads在移动下一个buffer前,必须填满当前的buffer,这也意味着它不适用于动态消息(译者注:消息大小不固定)。换句话说,如果存在消息头和消息体,消息头必须完成填充(例如 128byte),Scattering Reads才能正常工作。

Grather 从多个buffer 写到一个channel中。

image.png

ByteBuffer headBuf=ByteBuffer.allocate(180);
ByteBuffer bodyBuf=ByteBuffer.allocate(1024);

ByteBuffer[] bufferArray = { header, body };
channel.write(bufferArray);

NIO selector

Selector 是一个用可以检测到1到多个 channel 通道,并且知晓是 write 还是read 状态的一个组件。由这个功能 可以用一个单线程管理多个channel,从而管理多个网络链接。
使用selector 的好处是可以用更少的线程处理多个通道。

PIP

管道可以链接两个线程之间的单向通信,source 是读取流的一端,shink是将要写入的端


image.png

NIO和IO的优势,使用场景

[NIO]
1.需要处理成千上完的请求,但是这些请求每次只是发送少量的数据.例如聊天服务器.
2.单个线程管理多个链接
[IO]
少量的链接,一次性发送大量的数据.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容