BIO、NIO、AIO及网络编程

一. 网络编程的一些基础

     1.先说明一下线程的挂起、阻塞、睡眠

        线程从创建、运行到结束总是处于下面五个状态之一:新建状态、就绪状态、运行状

        态、阻塞状态及死亡状态。下图是使用时间片轮转法的操作系统进程的状态和它们之

        间的转换。

               挂起和睡眠是主动的,挂起恢复需要主动完成,睡眠恢复则是自动完成的,因为

        睡眠有一个睡眠时间,睡眠时间到则恢复到就绪态。而阻塞是被动的,是在等待某种

        事件或者资源的表现,一旦获得所需资源或者事件信息就自动回到就绪态。睡眠和挂

        起是两种行为,阻塞则是一种状态。

        挂起:一般是主动的,由系统或程序发出,甚至于辅存中去join()、wait()是挂起。

        阻塞:一般是被动的,在抢占资源中得不到资源,被动的挂起在内存,等待某种资

                   源或信号量(即有了资源)将他唤醒。sleep()是属于阻塞。

     2.同步/异步

        同步和异步关注的是消息通信机制。

      (1)同步:就是指在发出一个功能调用时,在没有得到结果之前,该调用就不返回。

                          按照这个定义,其实绝大多数函数都是同步调用。

      (2)异步:概念和同步相对。 当一个异步过程调用发出后,调用者不会立刻得到结

                          果。实际处理这个调用的部件是在调用发出后, 通过状态、通知来通知

                          调用者,或通过回调函数处理这个调用。

      举例:当到银行后, .可以去ATM机前排队等候 – (排队等候)就是同步等待消息 .可以去

                 大厅拿号,等到排到我的号时, 柜台的人会通知我轮到我去办理业务. – (等待别

                 人通知)就是异步等待消息。

     3.阻塞/非阻塞

        阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态(无所谓同

        步或者异步,注意这里的“调用结果”就是指“2”中标黑的“调用”的结果)

      (1)阻塞:阻塞调用是指调用结果返回之前,当前线程会被挂起(被挂起就是阻塞,

                          因为是被动的)。函数只有在得到结果之后才会返回。 有人也许会把阻

                          塞调用和同步调用等同起来,实际上他是不同的。 对于同步调用来说,

                          很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。

      (2)非阻塞:非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不

                             会阻塞当前线程,而会立刻返回。

        举例:继续上面的那个例子,不论是排队等待,还是使用号码等待通知,如果在这个

                   等待的过程中,等待者除了等待消息之外不能做其它的事情,那么该机制就是

                   阻塞的,表现在程序中,也就是该程序一直阻塞在该函数调用处不能继续往下

                   执行。相反,有的人喜欢在银行办理这些业务的时候一边打打电话发发短信一

                   边等待,这样的状态就是非阻塞的。

二. Java BIO、NIO、AIO

      1.概念

       (1)Java BIO : 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连

                                    接请求时服务器端就需要启动一个线程进行处理,如果这个连接不

                                    做任何事情会造成不必要的线程开销,当然可以通过线程池机制改

                                    善。

                                    好理解的解释:线程发起IO请求,不管内核是否准备好IO操作,从

                                                             发起请求起,线程一直阻塞,直到操作完成。

       (2)Java NIO : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送

                                     的连接请求都会注册到多路复用器上,多路复用器轮询到连接有

                                     I/O请求时才启动一个线程进行处理。

                                     好理解的解释:线程发起IO请求,立即返回;内核在做好IO操作的

                                                              准备之后,通过调用注册的回调函数通知线程做IO

                                                              操作,线程开始阻塞,直到操作完成。

       (3)Java AIO(NIO.2) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客

                                                户端的I/O请求都是由OS先完成了再通知服务器应用去启动

                                                线程进行处理。

                                                好理解的解释:线程发起IO请求,立即返回;内存做好IO操

                                                                         作的准备之后,做IO操作,直到操作完成或

                                                                         者失败,通过调用注册的回调函数通知线程

                                                                         做IO操作完成或者失败

      二. BIO、NIO、AIO的使用场景

          (1)BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比

                   较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

          (2)NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,

                   并发局限于应用中,编程比较复杂,JDK1.4开始支持。

          (3)AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,

                  充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

 

猜你喜欢

转载自blog.csdn.net/jialanshun/article/details/79234122