问题描述
public void run() { exitRequest = false ; while( !exitRequest) { try { // 初期化 socketChannel = SocketChannel.open() ; selector = Selector.open() ; socketChannel.socket().setReuseAddress( true) ; socketChannel.configureBlocking( false) ; socketChannel.socket().setReceiveBufferSize( RECV_BUFFER) ; selectionKey = socketChannel.register( selector, SelectionKey.OP_CONNECT) ; selectionKey.attach( new SocketNioControl( notifyObject, selector, socketChannel, selectionKey)) ; socketChannel.connect( inetAddress) ; int timer = 0 ; while( !socketChannel.isConnected()) { selector.select(100) ; if( exitRequest) { break ; } for( SelectionKey key : selector.selectedKeys()) { if( key.isConnectable()) { SocketChannel socketChannel = ( SocketChannel)key.channel() ; SocketNioControl socketControl = ( SocketNioControl)key.attachment() ; socketChannel.finishConnect() ; key.interestOps( SelectionKey.OP_READ) ; socketControl.connect() ; break ; } } if( timer >= TIMER_CONNECT * 1000) { throw new ConnectException() ; } timer += 100 ; } try { while( !exitRequest) { selector.select() ; for( SelectionKey key : selector.selectedKeys()) { SocketNioControl socketControl = ( SocketNioControl)key.attachment() ; if( key.isReadable()) { socketControl.read() ; } if( key.isWritable()) { socketControl.write() ; } } } } catch ( ConnectException ioex) { } catch ( CancelledKeyException ckex) { } } catch ( UnknownHostException uhex) { ErrorMessage.logging( uhex) ; } catch ( Exception ex) { ErrorMessage.logging( ex) ; } finally { try { for( SelectionKey key : selector.keys()) { SocketNioControl socketControl = ( SocketNioControl)key.attachment() ; socketControl.disconnect() ; } if( selector != null) { selector.close() ; selector = null ; } for( int timer = 0; timer < TIMER_RETRY * 1000; timer += 100) { Thread.sleep( 100) ; if( exitRequest) { break ; } } } catch( IOException ioe) { } catch( InterruptedException iex) { } } } } 线程一直被占用,导致系统hungup.是哪里出问题呢?另外 selector.select() 的值一直是0;这一句是起什么作用的?
解决方案
处理完某个事件后记得重新注册感兴趣的操作。尤其是写操作,系统大部分时候都是可写的,因此你如果不取消对写的注册,那就会不停地得到写就绪事件,其实就是死循环了。请参考这个正确的写法:http://teasp.iteye.com/admin/blogs/1884408
解决方案二:
key拿出后要remove 初学者经常忘记这个 不remove会死循环的Set<SelectionKey> keys = selector.selectedKeys();Iterator<SelectionKey> itr = keys.iterator(); while (itr.hasNext()) { SelectionKey key = itr.next(); itr.remove();
解决方案三:
如果是hangup的话,你最好用jstack 看看挂在哪儿
解决方案四:
selector.select() 是不会返回零的 除非执行了wakeup。只有selector.select(timeout) 当超时以后没有有事件的channel,才会返回零,你是指的那个select,假设是selector.select() 返回0,有可能是错误的wakeup。key.interestOps( SelectionKey.OP_READ) ;这句code应该可以取消write只设置read了吧
解决方案五:
稍微仔细看了下,问题太多。