JAVA BIO\NIO\AIO的入门学习

对网络编程中五种IO模型的理解

阻塞式I/O模型

é»å¡IO

没有资源,挂起资源,等待有资源了,将进程变为就绪态。

非阻塞式I/O模型

éé»å¡IO

没有资源,不断的轮询请求,直到有资源。

I/O多路复用(事件驱动)模型

IOå¤ç¨æ¨¡å

I/O多路复用,I/O就是指的我们网络I/O,多路指多个TCP连接(或多个Channel),复用指复用一个或少量线程。串起来理解就是很多个网络I/O复用一个或少量的线程来处理这些TCP连接。

信号驱动式I/O(SIGIO)

ä¿¡å·é©±å¨IO

这种IO模型主要用在嵌入式开发。

 

异步I/O模型

å¼æ­¥IO

IO请求发出之后,后台会建立一个进程,处理IO,当IO都处理完之后,把处理完的数据交给IO的请求者。(他的数据请求和数据处理都是异步的,数据请求一次返回一次,适用于长连接的业务场景)

 

对Linux中同步,异步,阻塞,非阻塞的概念理解

同步:执行一个操作之后,等待结果,然后才继续执行后续的操作。

异步:执行一个操作后,可以去执行其他的操作,然后等待回调通知再回来执行刚才没执行完的操作。

阻塞:进程或线程被阻塞(挂起),等到资源后进入(就绪态),可以竞争cpu资源。

非阻塞:没有等到资源的情况下,不会挂起线程,而是不停的轮询是否有资源,cpu开销较大。

经典的烧水例子:

你妈妈让你烧水,小时候比较笨啊,在哪里傻等着水开(同步阻塞)。等你稍微再长大一点,你知道每次烧水的空隙可以去干点其他事,然后只需要时不时来看看水开了没有(同步非阻塞)。后来,你们家用上了水开了会发出声音的壶,这样你就只需要听到响声后就知道水开了,在这期间你可以随便干自己的事情,你需要去倒水了(异步)。

异步情况下,不存在阻塞与不阻塞的问题,异步情况下,水开了会自动通知这里水开了,阻塞不阻塞取决于后续是不是需要用开水。急着用(水不开啥都做不了),就阻塞这里,等返回水开的结果。不急着用,就可以忙别的事情了。

对BIO\NIO\AIO的整体感官

java BIO(同步阻塞) 

简单理解:一个线程处理一个连接,发起和处理IO请求都是同步的。

在JDK1.4之前,用Java编写网络请求,都是建立一个ServerSocket,然后,客户端建立Socket时就会询问是否有线程可以处理,如果没有,要么等待,要么被拒绝。即:一个连接,要求Server对应一个处理线程。

java NIO(同步非阻塞

简单理解:一个线程处理多个连接,发起IO请求是非阻塞的但处理IO请求是同步的。

NIO本身是基于事件驱动思想来完成的,其主要想解决的是BIO的大并发问题。 在使用同步I/O的网络应用中,如果要同时处理多个客户端请求,或是在客户端要同时和多个服务器进行通讯,就必须使用多线程来处理。也就是说,将每一个客户端请求分配给一个线程来单独处理。这样做虽然可以达到我们的要求,但同时又会带来另外一个问题。由于每创建一个线程,就要为这个线程分配一定的内存空间,而且操作系统本身也对线程的总数有一定的限制。如果客户端的请求过多,服务端程序可能会因为不堪重负而拒绝客户端的请求,甚至服务器可能会因此而瘫痪。

NIO基于Reactor,当socket有流可读或可写入socket时,操作系统会相应的通知引用程序进行处理,应用再将流读取到缓冲区或写入操作系统。也就是说,这个时候,已经不是一个连接就要对应一个处理线程了,而是有效的请求,对应一个线程,当连接没有数据时,是没有工作线程来处理的。

NIO的特点:事件驱动模型、单线程处理多任务、非阻塞I/O,I/O读写不再阻塞,而是返回0、基于block的传输比基于流的传输更高效、更高级的IO函数zero-copy、IO多路复用大大提高了Java网络应用的可伸缩性和实用性。基于Reactor线程模型。

BIO是面向流的,NIO是面向缓冲区的;BIO的各种流是阻塞的。而NIO是非阻塞的;BIO的Stream是单向的,而NIO的channel是双向的。

java AIO(异步非阻塞IO)

简单理解:一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。

与NIO不同,操作系统负责处理内核区/用户区的内存数据迁移和真正的IO操作,应用程序只须直接调用API的read或write方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。 

不但线程等待资源是非阻塞的,就连数据从网卡到内存(内核区到用户区)的过程也是异步的。

再看java中的异步,同步,阻塞,非阻塞

同步异步取决于线程是否被挂起,阻塞非阻塞取决于数据从内核区到用户区是否是异步的。

深入了解NIO与AIO

java NIO的核心组成

通道(Channel) 和 缓冲区(Buffer)

基本上,所有的 IO 在NIO 中都从一个Channel 开始。Channel 有点象流。 数据可以从Channel读到Buffer中,也可以从Buffer 写到Channel中。
screenshot.png

多路复用器(Selector)

Selector允许单线程处理多个Channel。如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector就会很方便。例如,在一个聊天服务器中。

这是在一个单线程中使用一个Selector处理3个Channel的图示:

selector

要使用Selector,得向Selector注册Channel,然后调用它的select()方法。这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件,事件的例子有如新连接进来,数据接收等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值