关于java nio在windows下实现

本文探讨了Java 1.4 引入的 NIO 在 Windows 平台上的实现方式,指出其实现依赖于 select 模型而非 IOCP,这限制了其并发性能,并详细分析了相关代码。
java 1.4提供了nio,也就是之前我的一片博客中所说的multiplexed non-blocking I/O。这种模型比阻塞模型的并发性能要好一些,Java很多的网络应用都因此重写了底层模块,包括Tomcat、Jetty等等,也出现了基于nio的框架mina、国产的cindy等等。

java nio带来的影响是巨大的,得到了很多拥护和赞赏。

不过有一些是谣言,例如windows下的实现是Windows中并发性能最好的I/O模型IOCP,但事实上是这样么?

JDK 6.0 RC版提供了源码下载,下载路径: http://www.java.net/download/jdk6/jdk-6-rc-src-b104-jrl-01_nov_2006.jar

我们看最终Windows的实现:
j2se\src\windows\native\sun\nio\ch\WindowsSelectorImpl.c


82行开始:
ExpandedBlockStart.gif ContractedBlock.gif      /**/ /* Call select */
None.gif    
if  ((result  =  select( 0  ,  & readfds,  & writefds,  & exceptfds, tv)) 
ExpandedBlockStart.gifContractedBlock.gif                                                             
==  SOCKET_ERROR)  dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//* Bad error - this should not happen frequently */
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//* Iterate over sockets and call select() on each separately */
InBlock.gif        FD_SET errreadfds, errwritefds, errexceptfds;
InBlock.gif        readfds.fd_count 
= 0;
InBlock.gif        writefds.fd_count 
= 0;
InBlock.gif        exceptfds.fd_count 
= 0;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
for (i = 0; i < numfds; i++dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
/**//* prepare select structures for the i-th socket */
InBlock.gif            errreadfds.fd_count 
= 0;
InBlock.gif            errwritefds.fd_count 
= 0;
ExpandedSubBlockStart.gifContractedSubBlock.gif            
if (fds[i].events & POLLIN) dot.gif{
InBlock.gif               errreadfds.fd_array[
0= fds[i].fd;
InBlock.gif               errreadfds.fd_count 
= 1;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockStart.gifContractedSubBlock.gif            
if (fds[i].events & (POLLOUT | POLLCONN)) dot.gif{
InBlock.gif                errwritefds.fd_array[
0= fds[i].fd;
InBlock.gif                errwritefds.fd_count 
= 1;
ExpandedSubBlockEnd.gif            }

InBlock.gif            errexceptfds.fd_array[
0= fds[i].fd;
InBlock.gif            errexceptfds.fd_count 
= 1;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
/**//* call select on the i-th socket */
InBlock.gif            
if (select(0&errreadfds, &errwritefds, &errexceptfds, &zerotime) 
ExpandedSubBlockStart.gifContractedSubBlock.gif                                                             
== SOCKET_ERROR) dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif                
/**//* This socket causes an error. Add it to exceptfds set */
InBlock.gif                exceptfds.fd_array[exceptfds.fd_count] 
= fds[i].fd;
InBlock.gif                exceptfds.fd_count
++;
ExpandedSubBlockStart.gifContractedSubBlock.gif            }
 else dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif                
/**//* This socket does not cause an error. Process result */
ExpandedSubBlockStart.gifContractedSubBlock.gif                
if (errreadfds.fd_count == 1dot.gif{
InBlock.gif                    readfds.fd_array[readfds.fd_count] 
= fds[i].fd;
InBlock.gif                    readfds.fd_count
++;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockStart.gifContractedSubBlock.gif                
if (errwritefds.fd_count == 1dot.gif{
InBlock.gif                    writefds.fd_array[writefds.fd_count] 
= fds[i].fd;
InBlock.gif                    writefds.fd_count
++;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockStart.gifContractedSubBlock.gif                
if (errexceptfds.fd_count == 1dot.gif{
InBlock.gif                    exceptfds.fd_array[exceptfds.fd_count] 
= fds[i].fd;
InBlock.gif                    exceptfds.fd_count
++;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }
            

这就是广泛应用在Winsock中使用的select模型,也众所周知,并发性能不是很好。而且FD_SETSIZE不能超过Windows下层提供者的限制,这个限制通常是1024。也就是说Windows下,JDK的nio模型,不能超过1024个连接,这个跟我之前做的测试结果相似。

而且,如果FD_SETSIZE很大的话,例如是1000,调用select之前,必须设置1000个socket,返回之后又必须检查这1000个socket。

也就说,Windows下使用SUN JDK java的nio,并不能提高很好的并发性能。
82642.html

温少的日志 2006-11-22 00:35 发表评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值