2009-08-31 38 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問題。然而,我看不到修改密鑰集的代碼。

祝你好運調試。我希望它能幫助