深入浅出java IO模型

一、同步和异步

同步:一个事件或者任务的执行,会使整个流程暂时等待,也就是说如果有多个任务要执行,必须要逐个进行。

异步:一个事件或者任务的执行,不会使整个流程暂时等待,也就是说如果有多个任务要执行,可以并发去执行。

同步和异步的关键在于一个事件或者任务的执行是否会导致整个流程暂时等待。也就是任务是逐个完成的吗

二、阻塞和非阻塞

阻塞:在某个事件或者任务执行的过程中,它发出了一个请求,但是由于该操作能够执行所需要的条件还没有达到,就会一直等待在那里,直到条件满足。

非阻塞:在某个事件或者任务执行的过程中,它发出了一个请求,如果请求条件不满足,会返回一个标志信息告知不满足,不需要一直在那里等待。

阻塞和非阻塞的关键在于,当发出请求时,如果不满足请求时是一直等待还是不需要等待。

三、阻塞IO和非阻塞IO

IO操作通常包括:对硬盘的读写、对socket的读写以及外围设备的读写

一个完整的IO请求读写操作包括

(1)查看数据是否就绪;

(2)进行数据拷贝;

当线程发出一个IO请求操作的时候,内核会查看所需要读写的数据是否已经准备就绪,

阻塞IO:如果数据没有准备就绪,就一直等待,直到数据准备就绪;

非阻塞IO:如果没有准备就绪会返回一个标志信息,不需要等待,等到数据准备就绪以后,内核会把数据拷贝到线程中去。

阻塞IO和非阻塞IO关键在于数据没有准备好时是否会等待;

四、同步IO和异步IO

同步IO:当一个线程请求进行IO操作时,当IO操作完成之前,该线程会被阻塞;

当线程发送IO请求操作时,数据没有准备就绪,就会使用线程或者内核不停地去询问数据有没有准备好,当数据准备就绪后将数据从内核拷贝到线程。

异步IO:当一个线程请求进行IO操作时,当IO操作完成之前,该线程会不会被阻塞;

异步IO只有IO操作请求是线程发出的,查看数据是否准备和对数据的拷贝都是通过内核来完成的,发送通知告知线程IO操作已经完成,在异步IO中,不会对线程产生任何阻塞。

同步IO和异步IO都是的关键区别在于数据拷贝阶段是由线程完成还是内核完成。所以异步IO必须要有底层操作系统的支持。

五、5种IO模型

同步IO

(1)阻塞IO

如果数据没有准备就绪,就一直等待,直到数据准备就绪;就是传统的IO模型。

(2)非阻塞IO

如果没有准备就绪会返回一个标志信息,不需要等待,等到数据准备就绪以后,内核会把数据拷贝到线程中去。但是需要不断询问内核是否已经准备好数据,非阻塞虽然不用等待但是一直占用CPU。

(3)多路复用IO

Java NIO就是多路复用IO模型

多路复用IO,会有一个线程不断地去轮询多个socket的状态,当socket有读写事件的时候才会调用IO 读写操作。

用一个线程管理多个socket,是通过selector.select()查询每个通道是否有事件到达,如果没有事件到达,则会一直阻塞在那里,因此也会带来线程阻塞问题。

(4)信号驱动IO模型

在信号驱动IO模型中,当用户发起一个IO请求操作时,会给对应的socket注册一个信号函数,线程会继续执行,当数据准备就绪的时候会给线程发送一个信号,线程接受到信号时,会在信号函数中进行IO操作。

非阻塞IO、多路复用IO、信号驱动IO都不会造成IO操作的第一步,查看数据是否准备就绪而带来的线程阻塞,但是在第二步,对数据进行拷贝都会使线程阻塞。

异步IO

异步IO是最理想的IO模型,当线程发出一个IO请求操作时,接着就去做自己的事情了,内核去查看数据是否准备就绪和准备就绪后对数据的拷贝,拷贝完以后内核会给线程发送一个通知说整个IO操作已经完成了,数据可以直接使用了。

同步的IO操作在第二个阶段,对数据的拷贝阶段,都会造成线程的阻塞,异步IO则不会。

异步IO在IO操作的两个阶段,都不会使线程阻塞。

版权声明:本文转载自: https://blog.csdn.net/snow_7/article/details/51952796

猜你喜欢

转载自www.cnblogs.com/momoyan/p/9147926.html