2

私はjava.util.ConcurrentModificationExceptionこの方法で以下を得ています

private AtomicReference<HashMap<String, Logger>> transactionLoggerMap = new AtomicReference<HashMap<String,Logger>>();

public void rolloutFile() {

    // Get all the loggers and fire a temp log line.
    Set<String> transactionLoggerSet = (Set<String>) transactionLoggerMap.get().keySet();
    Iterator<String> transactionLoggerSetIter = transactionLoggerSet.iterator();
    while(transactionLoggerSetIter.hasNext()){
        String key = (String) transactionLoggerSetIter.next();
        Logger txnLogger = transactionLoggerMap.get().get(key);
        localLogger.trace("About to do timer task rollover:");
        txnLogger.info(DataTransformerConstants.IGNORE_MESSAGE);
    }
}

アトミックリファレンスを使用している場合、どうすればコモを取得できますか?

4

4 に答える 4

9

AConcurrentModificationExceptionは、反復子の外でコレクションを変更したことを意味します。ループに変更が見られないので、ループをtransactionLoggerMap繰り返しているのと同時に、ループに追加または削除している別のスレッドがあると思います。

でラップしたとしてもAtomicReference、2 つのスレッドが同じ非同期コレクションを同時に変更することはできません。 AtomicReferenceラップしているオブジェクトを同期しませ。その参照をアトミックに取得および設定する方法を提供するだけです。

クラスを使用するか、メソッドを使用してConcurrentHashMapラップすることにより、これを同期コレクションにする必要があります。HashMapCollections.synchronizedMap(map)

于 2012-05-18T19:16:07.260 に答える
1

同じコレクションではなく、コレクションのローカル コピーを反復処理することを検討してください。ループ中にコレクションが変更されないようにする簡単な方法です。マルチスレッド環境では不変オブジェクトを使用することをお勧めします。この種の問題は無料で防ぐことができます。

それが役に立てば幸い。

于 2012-05-18T19:19:16.173 に答える
1

反復中の同時変更から保護していないためです。Atomic リファレンスは、マップ (およびそのコンテンツ) を確実に取得するだけです。

于 2012-05-18T19:15:51.847 に答える
0

重複 Set<String> transactionLoggerSet = (Set<String>) transactionLoggerMap.get().keySet(); を削除するマップを反復処理しているため、同期を使用する必要があります。SynchronizedMap は、その API メソッドの一貫性を保証します。残りについては、クライアント側の同期を行う必要があります

于 2012-05-20T18:51:35.437 に答える