请教一个关于NIO执行方式的问题

04-03-01 wy123456789
用一般的DatagramSocket监听端口上的消息用如下代码
while(isRun){

receiverByte=new byte[Global.DATAGRAM_BYTES];
receiverDatagramPacket=new DatagramPacket
(receiverByte,receiverByte.length);

try{
1: receiverDatagramSocket.receive(receiverDatagramPacket);
}catch(IOException ex){
ex.printStackTrace();
}
//do something for packet
}

此种方法在1:处会阻塞

使用NIO的代码

DatagramChannel dc = DatagramChannel.open() ;
dc.configureBlocking( false ) ;
InetSocketAddress address = new InetSocketAddress( InetAddress.
getLocalHost() , 9000 ) ;

DatagramSocket s = dc.socket() ;
s.bind( address ) ;

Selector select = Selector.open() ;
SelectionKey key = dc.register( select , SelectionKey.OP_READ ) ;

ByteBuffer cb = ByteBuffer.allocate( 100 ) ;

while(true){
cb.clear() ;

int num = select.select() ; 2:

Set selectedKeys = select.selectedKeys() ;
Iterator it = selectedKeys.iterator() ;


while( it.hasNext() ){
SelectionKey k = ( SelectionKey )it.next() ;
if( ( k.readyOps() & SelectionKey.OP_READ )
== SelectionKey.OP_READ ){
DatagramChannel cc = ( DatagramChannel )k.channel() ;
cc.receive( cb ) ;
System.out.println( new String( cb.array() ) ) ;
}
}
}

此方法在2:处阻塞,仍然使用无限循环监听端口,这样与一般方法不就是一样了吗?
NIO的中断 方式不就没什么意义了么?怎样以次来提高性能呢?

2者本质上有何区别

wy123456789
2004-03-01 19:49
自己顶

传统方法,NIO其实都是使用轮询,那为什么NIO的效率高呢(除开Buffer的影响)

我简单的测试了一下,使用NIO接收一个UDP消息,与传统方法差不多(还稍微差一点)

banq
2004-03-03 09:36
NIO写法不对的。
NIO就是无堵塞,特别是访问量特别大,并发很厉害是显现。

wy123456789
2004-03-03 18:57
在Set selectedKeys = select.selectedKeys() ;处
是否阻塞??

如果此处不阻塞,则会不停的While循环(虽然什么也不作),不是降低了效率么,

banq
2004-03-04 09:31
不停的循环是查询数据,需要加一个sleep,否则CPU被你这个线程霸占了。

Set selectedKeys = select.selectedKeys() 不会堵塞,关于NIO见
http://www.jdon.com/concurrent/nio%D4%AD%C0%ED%D3%A6%D3%C3.htm

其实是一个轮询原理。

snp1103
2004-11-30 17:07
板桥大哥:
我觉得你说得不对, 因为jdk上面这样说的:
Selects a set of keys whose corresponding channels are ready for I/O operations.
This method performs a blocking selection operation. It returns only after at least one channel is selected, this selector's wakeup method is invoked, or the current thread is interrupted, whichever comes first.
况且在你的提到的链接的例子里面, 你也是在做循环, 没有使用sleep或wait()方法的
请您指正!


猜你喜欢