昨日与某平安的技术负责人沟通交流项目问题,谈到到线程和进程的问题,进而延伸到IO操作的问题,今天正好回顾一下关于IO操作里面的几个知识点。
参考文章:Java BIO、NIO、AIO 学习http://blog.51cto.com/stevex/1284437
先来个例子理解一下概念,以银行取款为例:
同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO时,Java自己处理IO读写)。
异步 : 委托一小弟拿银行卡到银行取钱,然后给你(使用异步IO时,Java将IO读写委托给OS处理,需要将数据缓冲区地址和大小传给OS(银行卡和密码),OS需要支持异步IO操作API)。
阻塞 : ATM排队取款,你只能等待(使用阻塞IO时,Java调用会一直阻塞到读写完成才返回)。
非阻塞 : 柜台取款,取个号,然后坐在椅子上做其它事,等号广播会通知你办理,没到号你就不能去,你可以不断问大堂经理排到了没有,大堂经理如果说还没到你就不能去(使用非阻塞IO时,如果不能读写Java调用会马上返回,当IO事件分发器会通知可读写时再继续进行读写,不断循环直到读写完成)。
以上为文章的例子,读完以后其实有点confused。毕竟对于异步和非阻塞来说,都有点类似于委托,do one thing,and no need to wait for response.而同步类同于阻塞,就是一种waiting的状态,直到事情finish。
我仔细想了一下关于这4个知识点,我觉得以下的理解比较符合我的思维方式:
1.同步与异步,是相对于调用者而言的。对于调用进程or线程而言,如果调用以后立马能够get response,不管调用的结果是否真正执行完,则属于异步。如果调用以后,要等调用的子系统完成执行的任务,整个进程或者处于waiting status,则是同步。
2.阻塞与非阻塞,则是相对于具体的IO操作本身。IO操作,是内核级别的,如果一个线程发起IO操作以后,该线程调用内核IO,线程一直处于blocked状态,直到该iO操作返回结果,则线程关闭,这属于阻塞。而非阻塞,则一个线程发起的IO请求,一般会进行一个POOL进行管理,待有资源时去执行该请求,而不是线程一直处于活跃状态。
NIO:同步非阻塞,用户发起IO操作,可以边做其它事情边轮训IO操作是否完成。JAVA的NIO属于此种模式;
BIO:同步阻塞,用户发起IO操作,需要等待内核IO操作完成,然后才能do another things;
AIO:异步,用户进程发起IO操作,不等内核IO完成,直接do another things,当内核完成IO以后通知进程;