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行開始:

????/**//*?Call?select?*/
????if?((result?=?select(0?,?&readfds,?&writefds,?&exceptfds,?tv))?

?????????????????????????????????????????????????????????????==?SOCKET_ERROR)?
{

????????/**//*?Bad?error?-?this?should?not?happen?frequently?*/

????????/**//*?Iterate?over?sockets?and?call?select()?on?each?separately?*/
????????FD_SET?errreadfds,?errwritefds,?errexceptfds;
????????readfds.fd_count?=?0;
????????writefds.fd_count?=?0;
????????exceptfds.fd_count?=?0;

????????for?(i?=?0;?i?<?numfds;?i++)?
{

????????????/**//*?prepare?select?structures?for?the?i-th?socket?*/
????????????errreadfds.fd_count?=?0;
????????????errwritefds.fd_count?=?0;

????????????if?(fds[i].events?&?POLLIN)?
{
???????????????errreadfds.fd_array[0]?=?fds[i].fd;
???????????????errreadfds.fd_count?=?1;
????????????}

????????????if?(fds[i].events?&?(POLLOUT?|?POLLCONN))?
{
????????????????errwritefds.fd_array[0]?=?fds[i].fd;
????????????????errwritefds.fd_count?=?1;
????????????}
????????????errexceptfds.fd_array[0]?=?fds[i].fd;
????????????errexceptfds.fd_count?=?1;


????????????/**//*?call?select?on?the?i-th?socket?*/
????????????if?(select(0,?&errreadfds,?&errwritefds,?&errexceptfds,?&zerotime)?

?????????????????????????????????????????????????????????????==?SOCKET_ERROR)?
{

????????????????/**//*?This?socket?causes?an?error.?Add?it?to?exceptfds?set?*/
????????????????exceptfds.fd_array[exceptfds.fd_count]?=?fds[i].fd;
????????????????exceptfds.fd_count++;

????????????}?else?
{

????????????????/**//*?This?socket?does?not?cause?an?error.?Process?result?*/

????????????????if?(errreadfds.fd_count?==?1)?
{
????????????????????readfds.fd_array[readfds.fd_count]?=?fds[i].fd;
????????????????????readfds.fd_count++;
????????????????}

????????????????if?(errwritefds.fd_count?==?1)?
{
????????????????????writefds.fd_array[writefds.fd_count]?=?fds[i].fd;
????????????????????writefds.fd_count++;
????????????????}

????????????????if?(errexceptfds.fd_count?==?1)?
{
????????????????????exceptfds.fd_array[exceptfds.fd_count]?=?fds[i].fd;
????????????????????exceptfds.fd_count++;
????????????????}
????????????}
????????}
????}????????????這就是廣泛應用在Winsock中使用的select模型,也眾所周知,并發性能不是很好。而且FD_SETSIZE不能超過Windows下層提供者的限制,這個限制通常是1024。也就是說Windows下,JDK的nio模型,不能超過1024個連接,這個跟我之前做的測試結果相似。
而且,如果FD_SETSIZE很大的話,例如是1000,調用select之前,必須設置1000個socket,返回之后又必須檢查這1000個socket。
也就說,Windows下使用SUN JDK java的nio,并不能提高很好的并發性能。