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,並不能提高很好的並發效能。
溫少的日誌 2006-11-22 00:35 發表評論