2009-08-31 69 views
0

我正在使用java nio选择器,并且似乎在调用selector.close时随机地在我的应用程序中碰到以下问题。选择器对象正被我的应用程序中的单个线程访问。相同的应用程序在Solaris,Linux和Windows上运行良好。我觉得这是一个问题与AIX实现选择的Selector.close在AIX平台上抛出java.util.ConcurrentModificationException

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的版本

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 

任何指针表示赞赏,

由于提前,

维杰

回答

-1

该解决方案包括以下修正:

  1. 同步的参与选择键的修改操作。
  2. 在调用Selector.close()之前,取消所有在选择器中注册的SelectionKeys。
  3. 在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 
         } 
        } 
    
0

您是否有另一个正在迭代/修改的线程选择器的关键集合?从Selector的java文档中,键不是线程安全的。

并发

选择器本身是由多个并发线程安全使用 ;然而,他们的 键集不是。 ...

您可能会得到CME异常如果在调用Selector.close()时您有一个线程在键集上工作。查看堆栈跟踪,Sun的常见实现代码中发生异常,因此它不应该是AIX特定的实现。我的建议是识别添加/删除选择键的线程,并查看是否需要应用同步关键字,或者在处理键之前需要创建同步副本。如果修改线程不是您的线程/代码,那么这是AIX问题。然而,我看不到修改密钥集的代码。

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

相关问题