Selector.close在AIX平台上抛出java.util.ConcurrentModificationException

时间:2009-08-31 07:35:23

标签: java network-programming selector nio

我正在使用java nio选择器,并且在调用selector.close时似乎在我的应用程序中随机但是一致地遇到了以下问题。我的应用程序中的单个线程正在访问选择器对象。相同的应用程序在Solaris,Linux和Windows上运行良好。我觉得这是一个问题,就是选择器的AIX实现

java.util.ConcurrentModificationException   
 at java.util.HashMap$AbstractMapIterator.checkConcurrentMod(HashMap.java:118)   
 at java.util.HashMap$AbstractMapIterator.makeNext(HashMap.java:123)   
 at java.util.HashMap$KeyIterator.next(HashMap.java:196)   
 at sun.nio.ch.SelectorImpl.implCloseSelector(SelectorImpl.java:95)   
 at java.nio.channels.spi.AbstractSelector.close(AbstractSelector.java:102)   
 at org.beepcore.beep.transport.tcp.TCPSelector.close(TCPSelector.java:173)   

java -version

java version "1.6.0"
Java(TM) SE Runtime Environment (build pap6460sr5ifix-20090729_01(SR5+IZ55981))
IBM J9 VM (build 2.4, J2RE 1.6.0 IBM J9 2.4 AIX ppc64-64 jvmap6460sr5ifx-20090728_39709 (JIT enabled, AOT enabled)
J9VM - 20090728_039709_BHdSMr
JIT  - r9_20090518_2017
GC   - 20090417_AA)
JCL  - 20090529_01

赞赏任何指针,

提前致谢,

维杰

2 个答案:

答案 0 :(得分:0)

你有另一个迭代/修改Selector密钥集的线程吗?从Selector的java doc中,键不是线程安全的。

  

并发

     

选择器本身可以安全使用   通过多个并发线程;其   但是,键集不是。   ...

您可能会遇到CME异常如果在调用Selector.close()时有一个线程正在处理密钥集。查看堆栈跟踪,Sun的通用实现代码中发生了异常,因此它不应该是AIX特定的实现。我的建议是识别添加/删除选择键的线程,并查看是否需要应用synchronized关键字,或者在处理键之前需要进行同步复制。如果修改线程不是您的线程/代码,那么它就是AIX问题。但是,如果没有看到修改密钥集的代码,我无法分辨。

祝你好运调试。我希望它有所帮助

答案 1 :(得分:0)

解决方案包括以下修复:

  1. 同步修改选择键的操作。
  2. 在调用Selector.close()。
  3. 之前,取消向选择器注册的所有SelectionKeys
  4. 在selector.close()的包装函数中调用Selector.wakeup(),以便在调用close时立即退出选择线程。

        boolean isContinue = true;
        while(isContinue) {
            try {
                for(SelectionKey selectionKey : selector.keys()) {
                    selectionKey.channel().close();
                    selectionKey.cancel();
                }
                isContinue = false; // continue till all keys are cancelled
            } catch (ConcurrentModificationException e) {
                // This should not occur. But log a debug message in case this is encountered
            }
        }