同步与异步
的概念, 关注的是 消息通讯机制数组
同步
是指发出一个请求, 在没有获得结果以前该请求就不返回结果, 请求返回时, 也就获得结果了.好比洗衣服, 把衣服放在洗衣机里, 没有洗好以前咱们一直看着, 直到洗好了才拿出来晾晒.网络
异步
是指发出一个请求后, 马上获得了回应, 但没有返回结果. 这时咱们能够再处理别的事情(发送其余请求), 因此这种方式须要咱们经过状态主动查看是否有告终果, 或者能够设置一个回调来通知调用者.好比洗衣服时, 把衣服放到洗衣机里, 咱们就能够去作别的事情, 过会儿来看看有没有洗好(经过状态查询);
或者咱们设置洗衣机洗完后响铃来通知咱们洗好了(回调通知)异步
阻塞与非阻塞
很容易和同步与异步
混淆, 但二者关注点是不同的. 阻塞与非阻塞
关注的是 程序在等待调用结果时的状态socket
阻塞
是指请求结果返回以前, 当前线程会被挂起(被阻塞), 这时线程什么也作不了非阻塞
是指请求结果返回以前, 当前线程没有被阻塞, 仍然能够作其余事情.阻塞
有个明显的特征就是线程一般是处于BLOCKED
状态(BIO中的read()
操做时, 线程阻塞是JVM配合OS完成的, 此时Java获取到线程的状态还是RUNNABLE
但它确实已经被阻塞了)函数
若是要拿同步
来作比较的话, 同步通讯方式中的线程在发送请求以后等待结果这个过程当中应该处于RUNNABLE
状态, 同步必须一步一步来完成, 就像是代码必须执行完一行才能执行下一行, 因此必须等待这个请求返回以后才可进行下一个请求, 即便等待结果的时间长, 也是在执行这个请求的过程当中. 而异步
则不用等上一条执行完, 能够先执行别的代码, 等请求有告终果再来获取结果.操作系统
Java中的IO操做是JVM配合操做系统来完成的. 对于一个IO的读操做, 数据会先被拷贝到操做系统内核的缓冲区中, 而后从操做系统内核的缓冲区拷贝到应用程序的地址空间. 因此整个过程可分为两个阶段:线程
根据这两个阶段, 产生了常见的几种不一样的IO模型: BIO
, NIO
, IO多路复用
和AIO
.code
BIO
即Blocking I/O
(阻塞 I/O), BIO整个过程以下图:接口
程序发送请求给内核, 而后由内核去进行通讯, 在内核准备好数据以前这个线程是被挂起的, 因此在两个阶段程序都处于挂起状态.进程
NIO
即Non-Blocking I/O
(非阻塞 I/O), NIO整个过程以下图:
与BIO的明显区别是, 发起第一次请求后, 线程并无被阻塞, 它反复检查数据是否准备好, 把原来大块不能用的阻塞时间分红了许多”小阻塞”(检查), 因此进程不断有机会被执行. 这个检查有没有准备好数据的过程有点相似于”轮询”.
IO多路复用(I/O Multiplexing
)有select
, poll
, epoll
等不一样方式, 它的优势在于单个线程能够同时处理多个网络IO.
NIO
中轮询操做是用户线程进行的, 若是把这个任务交给其余线程, 则用户线程就不用这么费劲的查询状态了. IO多路复用
调用系统级别的select
或poll
模型, 由系统进行监控IO状态. select轮询能够监控许多socket的IO请求, 当有一个socket的数据准备好时就能够返回.
多路复用IO过程图:
用户线程有一段时间是阻塞的, 从上图来看, 与NIO
很像, 但与NIO不同的是, select不是等到全部数据准备好才返回, 而是只要有一个准备好就返回, 它的优点在于能够同时处理多个链接. 若链接不是不少的话, 它的效率不必定高, 可能还会更差.
Java 1.4
开始支持NIO(New IO)
, 就是采用了这种方式, 在套接字上提供selector
选择机制, 当发起select()
时会阻塞等待至少一个事件返回.
AIO
即Asynchronous I/O
(异步 I/O), 这是Java 1.7
引入的NIO 2.0
中用到的. 整个过程当中, 用户线程发起一个系统调用以后无须等待, 能够处理别的事情. 由操做系统等待接收内容, 接收后把数据拷贝到用户进程中, 最后通知用户程序已经可使用数据了, 两个阶段都是非阻塞的. AIO整个过程以下图:
AIO
属于异步模型, 用户线程能够同时处理别的事情, 咱们怎么进一步加工处理结果呢? Java在这个模型中提供了两种方法:
CompletionHandler
接口, 在调用时把回调函数传递给对应的API便可Future
. 处理完别的事情, 能够经过isDone()
可查看是否已经准备好数据, 经过get()
方法等待返回数据.上面这几种模式, BIO
整个过程都等待返回, NIO
和IO多路复用
在第二个阶段等待返回, 所以从整个过程来看, 这三个模式都属于同步方式. AIO
在整个过程当中没有等待返回, 属于异步方式.