Java NIO关闭一个通道导致另一个通道无响应

时间:2017-11-30 00:53:04

标签: java sockets concurrency network-programming nio

我刚发现问题可能是由于多线程问题。在read()方法之后,我将请求发送到几个工作线程来处理数据。当线程池大小为1时,不会发生此问题。但是,当线程池大小大于1时,会出现此问题。

我在while(true)循环之前初始化了我的线程池,并在read()方法之后执行了我的工作线程。

我在连接memtier客户端和memcached服务器的中间件中使用Java NIO。系统只能连接一个客户端,但是,当连接的客户端数量较多时,当一个客户端完成并关闭其通道时,另一个客户端将无法再读取或写入其通道。

我的实现如下:

public void run() {
    try{
         // Connect to client
         selector = Selector.open();
         ServerSocketChannel server = ServerSocketChannel.open();
         server.configureBlocking(false);

         InetSocketAddress address = new InetSocketAddress(8000);
         server.socket().bind(address);
         server.register(selector,SelectionKey.OP_ACCEPT);

         // Connect to Server
         Socket socket = new Socket("localhost",8090);

         // Select keys
         while (true) {
             selector.select();
             Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();

               while(iterator.hasNext()) {
                     SelectionKey key = iterator.next();
                     iterator.remove();

                     // check if key is valid
                     if(!key.isValid()) {
                           continue;
                     }

                     if(key.isAcceptable()) {
                         accept(key);
                     }else if(key.isReadable()) {
                         read(key);
                     }
               }
         }

    }
}

我的accept()和read()看起来像这样:

private void accept(SelectionKey key) {
   ServerSocketChannel server = (ServerSocketChannel) key.channel();
   SocketChannel socketChannel = server.accept();
   socketChannel.configureBlocking(false);
   socketChannel.register(selector, SelectionKey.OP_READ);
}

private void read(SelectionKey key) {
    SocketChannel channel = (SocketChannel) key.channel();
    buffer.clear();
    int n = -1;

    n = channel.read(buffer);

    if(n == -1) {
        key.cancel();
        channel.close();
    }else{
      //read to buffer

    }
}

我尝试了很多方法,但仍然无法找出问题所在。非常感谢你!

0 个答案:

没有答案