1

通常(つまり、同時にではない)、に渡す他のマップを構築するコストを除外したとしても、にputAll()多くの呼び出しを使用するよりも効率的ではありません。これは、渡されたMapの要素を反復処理する必要があるだけでなく、実行するMapに各キーと値のペアを追加するためのアルゴリズムを実行する必要があるためです。put()putAll()putAll()put()

putAll()しかし、ConcurrentHashMapの場合、通常のMapを作成してから、それを更新するために使用するのは理にかなっていますか?または、10回(または100回、または1000回)の呼び出しを行う必要がありput()ますか?

への複数の呼び出しの答えは変わりますputIfAbsent()か?

ありがとう!

4

2 に答える 2

4

Javaコレクションの最初の(ほとんど)スレッドセーフなマップは、HashMapを使用して同期されましたCollections.synchronizedMap()。一度に1つの操作のみを許可することで機能しました。Java 5はConcurrentHashMap、動作が異なるを追加しました。基本的にMapはスライスに分割されます。操作は、関連するput()スライスのみをロックします。また、のようなスレッドセーフプリミティブも追加しましたputIfAbsent()

私がこれを説明する理由は、それputAll()がどのように実装されているかに応じて、多かれ少なかれ効率的かもしれないということです。マップ全体をロックすることで機能する場合があります。これは、すべてので個別のロックを取得しようとするよりも実際に効率的である可能性がありますput()。または、put()とにかくたくさんの呼び出しを行うことで機能する場合があります。その場合、大きな違いはありません。

したがって、コードにとって意味があり、一度に多くの更新を行う場合は、それが必要putAll()でない限り、私が使用putIfAbsent()します。

編集:チェックしたところ、Java 6は操作のループとしてConcurrentHashMap実装されているため、これを自分で行うよりも良いことも悪いこともありません。putAll()put()

于 2009-11-05T02:22:39.187 に答える
2

putAll()に委任するだけput()です。まだ持っていない場合は、中間マップを作成する必要はありません。これはソースコードで確認できます。コードはパブリックドメインであり、すべてのJava実装で共有されているため、使用しているJava実装は関係ありません。

putAll()これはアトミックではなく、各個人がアトミックであるという保証があるだけであることに注意してくださいput()

于 2009-11-05T18:07:06.027 に答える