我正在使用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
赞赏任何指针,
提前致谢,
维杰
答案 0 :(得分:0)
你有另一个迭代/修改Selector密钥集的线程吗?从Selector的java doc中,键不是线程安全的。
并发
选择器本身可以安全使用 通过多个并发线程;其 但是,键集不是。 ...
您可能会遇到CME异常如果在调用Selector.close()时有一个线程正在处理密钥集。查看堆栈跟踪,Sun的通用实现代码中发生了异常,因此它不应该是AIX特定的实现。我的建议是识别添加/删除选择键的线程,并查看是否需要应用synchronized关键字,或者在处理键之前需要进行同步复制。如果修改线程不是您的线程/代码,那么它就是AIX问题。但是,如果没有看到修改密钥集的代码,我无法分辨。
祝你好运调试。我希望它有所帮助
答案 1 :(得分:0)
解决方案包括以下修复:
在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
}
}