2012-01-31 14 views
0

ConcurrentModificationExceptionこのコードでは何が得られますか?私は、同期(リスナー)ロックを持っています。ConcurrentModificationExceptionを取得しましたが、削除しません。

private void notifyListeners(MediumRendition rendition) { 
    if (rendition == null) return; 
    synchronized (listeners) { 
     for (RenditionEventListener l : listeners) { 
      if (l.renditionType.equals(rendition.getType()) && l.mediumId == rendition.getMediumId()) { 
       l.listener.onRendition(rendition); 
      } 
     } 
    } 
} 

public void put(String renditionType, long mediumId, MediumRendition rendition) { 
    HashMap<Long, MediumRendition> l = list.get(renditionType); 
    if (l == null) { 
     l = new HashMap<Long, MediumRendition>(); 
     list.put(renditionType, l); 
    } 
    l.put(mediumId, rendition); 
    notifyListeners(rendition); 
} 

public void addRenditionListener(String renditionType, long mediumId, RenditionListener listener) { 
    synchronized (listeners) { 
     listeners.add(new RenditionEventListener(renditionType, mediumId, listener)); 
    } 
} 

1月30日16:47:55.147 6953 6974 E AndroidRuntime:致命的な例外:スレッド1 1月30日16:47:55.147 6953 6974 E AndroidRuntime:java.util.ConcurrentModificationExceptionが 1月30日16:47:55.147 6953 6974 E AndroidRuntime:java.util.ArrayList $ ArrayListIterator.next(ArrayList.java:573) 01-30 16:47:55.147 6953 6974 E AndroidRuntime:at com。 .vos.RenditionList.notifyListeners(RenditionList.java:79) 1月30日16:47:55.147 6953 6974 E AndroidRuntime:COM.T .vos.RenditionList.put(RenditionList.java:41) 1月30日に16:47:55.147 6953 6974 E AndroidRuntime:。。com * controllers.OmwController $ 6.run(OmwController.java:212)解決しよう

で:どうやら私は削除しました。下記参照。

+2

['CME's(docs)](http://docs.oracle.com/javase/6/docs/api/java/util/ConcurrentModificationException.html)に起因する必要はありません。 *別のスレッド。 –

+0

他にリスナーにアクセスするには?それはまた同期されますか? –

+0

...そうだとすれば、ここにはどう? – user123321

答えて

5

例外は、リスナーが別のスレッドから変更されている可能性があることを示します。ですから、他のどこかで同期が取られていないかどうかを確認する必要があります。

また、onRendition()の実装がlistからlistenerを削除するかどうかを確認します。これは、複数のスレッドが関与していない場合、別の原因となる可能性があります。

+0

"複数のスレッドが関与していない場合、onRendition()の実装がlistenerをlistから削除するかどうかをチェックすることもできます...."そうです。本当にありがとう!!! – user123321

2

並行処理はややこしいです。アプリケーションのコンテキストでは、しかし、あなたが可能な解決策は以下の通りです

l.listener.onRendition(rendition); 

を呼び出すときにリストを変更していないが、それはどこかに修正なっていることを確認しないことがあります。

  1. ArrayListの代わりにConcurrentLinkedQueueを使用してください。このコレクションを使用する場合は、同期ブロックを作成する必要はありません。これは最も簡単な解決法です。
  2. 1.が機能しない場合は、ArrayListの代わりにCopyOnWriteArrayListを使用できます。リスナーを隠すときは、ArrayListの代わりにCopyOnWriteArrayListを使用することをお勧めします。
+1

+1は、CopyOnWriteArrayListがリスナーにとって望ましいことを指摘しています。 – user949300

関連する問題