Java NIO

NIO单线程编写高性能、高并发服务器  

2012-02-25 16:41:50|  分类: J2SE技术 |  标签:nio  java  socket  |举报|字号 订阅

 
 

           在传统的java网络编程中,都是在服务端创建一个ServerSocket,然后为每一个客户端单独创建一个线程Thread分别处理各自的请求,由于对于CPU而言,线程的开销是很大的,无限创建线程会让操作系统崩溃,因此,比较好的方法是在系统启动的时候创建一个动态的线程池,例如鼎鼎大名的服务器Tomcat,就是采用这种解决方案,然而,这种解决方案在高并发的情况下,情况就不太乐观了,当线程池大小超过CPU瓶颈的时候,相应速度,就极其低下了。

传统的java网络编程的结构图如下

Java NIO_第1张图片
 
 
 
       在JDK1.4后,java引入的NIO的概念,即非阻塞的IO,服务端无需创建多个线程,仅仅只需要1个线程(将读写分别创建线程有利于提高性能)即可以处理全部客户端,解决了在性能和并发的2大问题。

       NIO采用了通道Channel和选择器Selector的核心对象,Select 机制,不用为每一个客户端连接新启线程处理,而是将其注册到特定的Selector 对象上,这就可以在单线程中利用Selector 对象管理大量并发的网络连接,更好的利用了系统资源;采用非阻塞I/O 的通信方式,不要求阻塞等待I/O 操作完成即可返回,从而减少了管理I/O 连接导致的系统开销,大幅度提高了系统性能。

当有读或写等任何注册的事件发生时,可以从Selector 中获得相应的SelectionKey , 从SelectionKey 中可以找到发生的事件和该事件所发生的具体的SelectableChannel,以获得客户端发送过来的数据。由于在非阻塞网络I/O 中采用了事件触发机制,处理程序可以得到系统的主动通知,从而可以实现底层网络I/O 无阻塞、流畅地读写,而不像在原来的阻塞模式下处理程序需要不断循环等待。使用NIO,可以编写出性能更好、更易扩展的并发型服务器程序。

     NIO的结构如下

Java NIO_第2张图片

 由此可见,服务端最少只需要一个线程,既可以处理所有客户端Socket

NIO的设计原理

       设计原理有点像设计模式中的观察者模式,由Selector去轮流咨询各个SocketChannel通道是否有事件发生,如果有,则选择出所有的Key集合,然后传递给处理程序。我们通过每个key就可以获取客户端的SocketChannel,从而进行通信。

       如果Selector发现所有通道都没有事件发生,则线程进入睡眠状态Sleep,阻塞。等到客户端有事件发生,会自动唤醒wakeup选择器selector,是不是有点类似观察者模式!!!!

 

 

 

好下面通过一个案例,来说明NIO的通信机制

 

先看服务端程序

首先定义通信数据包DataPacket

Java NIO_第3张图片

 

 

 

核心NIO服务

Java NIO_第4张图片
Java NIO_第5张图片
Java NIO_第6张图片
Java NIO_第7张图片

 

 

最后是测试程序

Java NIO_第8张图片

 

 

 

 

 

 

下面是客户端程序

Java NIO_第9张图片
Java NIO_第10张图片

 

 

 

 

运行结果

Java NIO_第11张图片

 

Java NIO_第12张图片

 

 

 

这就是Java  NIO机制,具有网络跨时代的意义,apache的顶级项目Mina就是采用Java NIO机制,目前Tomcat7也增加的NIO的实现,可见NIO的力量是非常强大的。

你可能感兴趣的:(java,nio)