`

NIO的SelectableChannel关闭的一个问题

    博客分类:
  • java
阅读更多

    SocketChannel和ServerSocketChannel,两者的父类是SelectableChannel,它在jdk中的文档有这么段话:

 

   Once registered with a selector, a channel remains registered until it is deregistered.This involves deallocating whatever resources were allocated to the channel by the selector.
    A channel cannot be deregistered directly; instead, the key representing its registration must be cancelled. Cancelling a key requests that the channel be deregistered during the selector's next selection operation.

 

    也就是说关闭一个已经注册的SelectableChannel需要两个步骤:

1)取消注册的key,这个可以通过SelectionKey.cancel方法,也可以通过SelectableChannel.close方法,或者中断阻塞在该channel上的IO操作的线程来做到。

2)后续的Selector.selectXXX方法的调用才真正地关闭 本地Socket。

    因而,如果,如果在取消SelectionKey后没有调用到selector的select方法(因为Client一般在取消key后, 我们都会终止调用select的循环,当然,server关闭一个注册的channel我们是不会终止select循环的),那么本地socket将进入CLOSE-WAIT 状态(等待本地Socket关闭)。简单的解决办法是在 SelectableChannel.close方法之后调用Selector.selectNow方法,类似:

   Selector sel;
   SocketChannel sch;
   // …
   sch.close();
   sel.selectNow();


    Nio编程有很多这样细节性的东西需要注意,通常情况下还是利用成熟的框架为妙。

分享到:
评论
2 楼 nkd2002 2012-05-13  
你好,博主,
因而,如果,如果在取消SelectionKey后没有调用到selector的select方法(因为Client一般在取消key后,我们都会终止调用select的循环,当然,server关闭一个注册的channel我们是不会终止select循环的),那么本地socket将进入CLOSE-WAIT 状态(等待本地Socket关闭)。
这段话描述是不是不问题,CLOSE-WAIT是被动关闭socket一方才会有的状态,你说的key cancel或channel colse都是主动关闭方,怎么会有CLOSE-WAIT状态呢,不太明白。请博主解答。
1 楼 asme2u 2010-10-17  
早点来这里看看就好了 ,前段时间用NIO开发一个spider,就是因为这个问题搞得一大堆连接CLOSE_WAIT,最终程序以报too many open files收场,后来还是翻了HttpComponents才搞明白

相关推荐

    用nio实现异步连接池

    常连接是指一个持久存在的TCP连接,避免了频繁创建和销毁连接带来的系统资源消耗和性能损耗。然而,当应用需要与多个后台服务交互时,传统的串行处理模式(即逐一访问每个服务)会导致性能瓶颈和系统健壮性下降。 ...

    linux nio和java.zip

    5. `Pipe`:提供了一个单向的数据通道,用于在Java线程之间传递数据。 Java NIO的使用步骤通常包括: 1. 创建选择器并注册感兴趣的通道。 2. 配置通道为非阻塞模式。 3. 在循环中调用选择器的`select()`方法,获取...

    netty的自己写的文档

    - 每个Channel与一个ChannelHandlerContext相对应,而每个ChannelHandlerContext又与一个特定的Channel相关联。 #### ChannelPipeline - `ChannelPipeline`是一个包含多个`ChannelHandler`的链表,用于处理入站和...

    Socket编程QQ实现 JAVA

    QQ作为一个即时通讯软件,其背后的原理也离不开Socket通信。在这个项目中,我们将学习如何利用Java的Socket API来模拟实现一个简单的QQ聊天功能。 首先,理解Socket的概念至关重要。Socket在计算机网络中可以被视为...

    java selector 测试并发

    JavaSelector在Java NIO(非阻塞I/O)中扮演着关键角色,它允许程序同时监控多个通道(channels)的事件,例如连接请求、数据可用性或者关闭事件,而无需在一个单独的线程中轮询所有通道。这种机制极大地提高了处理...

    java7 新I/O知识点详解

    最后,Java 7的`try-with-resources`语句与NIO.2结合,使得资源关闭更加安全可靠,避免了传统的finally块可能导致的资源泄露问题。 总结来说,Java 7的NIO.2 API带来了以下关键改进: 1. 更强大的文件系统操作,如`...

Global site tag (gtag.js) - Google Analytics