weixin_42501955
2013-07-11 15:47
浏览 290
已采纳

java NIO 多线程

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;这一句是起什么作用的?

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

5条回答 默认 最新

  • teasp 2013-07-12 08:35
    已采纳

    处理完某个事件后记得重新注册感兴趣的操作。尤其是写操作,系统大部分时候都是可写的,因此你如果不取消对写的注册,那就会不停地得到写就绪事件,其实就是死循环了。请参考这个正确的写法:http://teasp.iteye.com/admin/blogs/1884408

    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • teasp 2013-07-12 08:48

    稍微仔细看了下,问题太多。

    评论
    解决 无用
    打赏 举报
  • tianshilang 2013-07-12 13:48

    selector.select() 是不会返回零的 除非执行了wakeup。只有selector.select(timeout) 当超时以后没有有事件的channel,才会返回零,你是指的那个select,假设是selector.select() 返回0,有可能是错误的wakeup。key.interestOps( SelectionKey.OP_READ) ;这句code应该可以取消write只设置read了吧

    评论
    解决 无用
    打赏 举报
  • tianshilang 2013-07-12 13:50

    如果是hangup的话,你最好用jstack 看看挂在哪儿

    评论
    解决 无用
    打赏 举报
  • jd2bs 2013-07-12 18:34

    key拿出后要remove 初学者经常忘记这个 不remove会死循环的
    Set keys = selector.selectedKeys();

    Iterator itr = keys.iterator();

    while (itr.hasNext())

    {

    SelectionKey key = itr.next();

    itr.remove();

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题