面试系列之IO模型

1.阻塞IO模型

最传统的IO模型,就是在读和写的过程中发生阻塞现象。
用户线程发起IO请求之后,内核会去检查数据是否已就绪。
如果未就绪,内核就会等待数据就绪,用户线程就会挂起,出让CPU。
当内核数据就绪,内核就会将数据拷贝到用户线程,并唤醒用户线程,解除阻塞状态。
典型的阻塞 IO 模型的例子为:
data = socket.read();
如果数据没有就绪,就会一直阻塞在 read 方法。

2.非阻塞 IO 模型

当用户线程发起一个read操作的时候,不会阻塞,而是立马得到一个结果。
如果结果是一个error,用户线程就知道数据还没准备好,又继续请求read操作。
一旦数据就绪,用户线程又继续发起read操作,内核就会拷贝数据到用户线程并返回。
也就数说,非阻塞IO实际上是不断的轮询检查数据是否准备好,而不会出让CPU。
典型的非阻塞IO例子:

while(true){
    data = socket.read();
    if(data!= error){
      // 处理数据
     break;
   }
}

这种方式,不断的轮询检查,cpu占用率就非常高。

3.多路复用 IO模型

多路复用IO模型是目前用的比较多的IO模型,比如Redis就是用该模型,java中的NIO也是用该模型。
多路复用IO模型就是有一个专门的线程负责管理所有的socket状态,这个线程去轮询多个socket的请求,只有socket有真正的读或写请求的时候,才会发起IO操作。
在多路复用IO模型中,只用一个线程来专门处理客户端连接,所以不必像前两种一样,一旦有客户端连接就新建一个线程,而且只有真正的客户端读写请求才会发起IO操作,这样就大大减少了资源的使用和占用。
在java nio中是用 selector.select()去查询有没有可可发起IO操作的通道,没有的就阻塞,一旦有一个用户线程有读写请求,就对该线程发起IO操作。
多路复用IO模型也是通过轮询的方式来检查数据是否准备,不过他只有一个线程而且是在内核中轮询检查的,非阻塞IO是每个用户线程各自轮询检查,显然资源占用率低,效率也会比较高。
要注意的是,多路复用IO毕竟还是用轮询的方式,一旦处理时间很长或者响应体很大响应时间很长,就会影响排队中的线程的等待时间。

4.信号驱动IO模型

当用户线程发起一个io请求的时候,会在socekt上注册一个信号函数,用户线程会继续执行它的流程,当数据准备就绪,内核会发送一个信号给用户线程,用户线程就会执行信号函数中的逻辑来发起IO操作。

5.异步IO模型

用户线程发起read操作的时候,立即去执行其他业务。内核收到一个异步读的请求之后,就开始等待数据准备完成,数据准备完成之后,内核会将数据拷贝到用户线程,拷贝完之后在通知用户线程数据已经读完。跟信号驱动不同的是,信号驱动只是收到一个信号,再去用信号函数读。异步IO是内核直接给你,在跟你说好了。

小结

阻塞IO:用户线程阻塞挂起
非阻塞IO:用户线程不阻塞了但是多个用户线程一直占用CPU
多路复用IO:只有一个后台线程占用cpu但是处理时间久的话,其他用户线程等待时间较长
信号驱动IO:线程可以立即去处理其他业务,但是还需要通过信号函数来发起IO操作
异步IO:不需要信号函数发起IO操作了,而是内核直接拷贝到用户线程并通知

6.java io包

java io包

7.java nio包

java nio包

8.java nio主要内容

传统的io是基于字节流或字符流来操作的,而java nio是基于缓冲和通道来操作的。
java nio主要包括:channel(通道)、buffer(缓冲)、selector(选择器)
也就是说,数据都是从通道读到缓存区,或者从缓存区写到通道,而选择器监听着多个通道的事件比如:链接打开事件,数据到达事件,所以单个线程可以监听多个通道。
另外,java io和java nio最大的区别就是,io是面向流的,nio是面向缓冲的


java nio模型

Channel:channel和io中的stream差不多是一个级别的,只不过stream是单向的比如:InputStream(读),OutputStream(写),而channel是双向的既可以读也可以写。
Buffer:buffer实际上就是一个容器,底层是一个连续数组。channel从文件或网络中读到的数据必须先经过buffer。


buffer

如上图:客户端发送请求先经过buffer在统一到channel,服务端接受数据也是先经过channel统一读到buffer中在进行处理。
selector:selector是nio中核心的类,一个selector能够注册多个channel,并且能够检测出多个channel的事件,只有真正有读写事件的时候才会发起io操作。这样依赖只要用一个线程就能管理多个连接,避免线程的上下文切换,减少系统的开销。

9.nio中的缓存区

java io是面向字节或字符的,意味着每次读写都是一个字节或多个字节,频繁的刷盘,而且没有缓存到一个地方也没办法前后移动流的数据。nio中的缓存区就是为了解决这些问题,每次读写都将数据暂存到缓存区然后在批量刷盘,而且还能够自由的前后移动读取缓存中的数据,增加了数据处理的效率和灵活性。

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

推荐阅读更多精彩内容