Java開発でストレスを感じる1つのミームは、常にVectorではなくArrayListを使用することです。ベクターは非推奨です。それは本当かもしれませんが、VectorとHashtableには同期されているという利点があります。
並行性の高いアプリケーションを使用していますが、Vectorのように同期されたオブジェクトを使用することにはメリットがありますか?彼らは彼らの場所を持っているようですか?
VectorとHashtableの問題は、ローカルでのみ同期されることです。並行アプリケーションでは(破損したデータのように)壊れることはありませんが、ローカル同期(たとえば、getは同期されますが、getが返されるまでのみ)により、次のような状況ではとにかく独自の同期を実行する必要があります。コンテンツの反復として。これで、put-methodでさえ、反復同期と連携するために追加の同期が必要になり、Hashtable/Vectorが二重に同期される状況になります。
ConcurrentHashMapはHashtableよりも高速です。同期だけでなく、並行です。一度に複数のリーダー/ライターを許可します。
ただし、そのような「同時」配列リストはありません。必要に応じて、CopyOnWriteArrayListが必要な場合とそうでない場合があります。
同期されたArrayListまたはHashMapが必要な場合は、それらをラップできます。
List list = Collections.synchronizedList(new ArrayList(...));
Map m = Collections.synchronizedMap(new HashMap(...));
個人的には、これらのコレクションの「同期された」メソッドは、ヘビースレッドコードではあまり役に立ちません。さらに役立つ新しいコレクションがいくつかありますが、ほとんどの場合、独自の同期オブジェクトを作成してそれらを中心に同期するか、java.util.concurrentの新しいロックを使用しています。
Vector
同期にはその役割がありますが、との違いはそれだけではありませんArrayList
。Vector
は、容量を超えるたびに内部ストレージ配列を固定量だけArrayList
拡大しますが、固定係数で拡大します。これは通常、はるかに優れたアプローチです (アイテムを追加するための償却コストが O(1) になるため)。
またCollections.synchronizedList()
、任意の実装で同期ビューを作成するために使用できるためList
、の特性に縛られる必要がないことに注意してください(たとえばVector
、同期が必要になる場合があります)。LinkedList
静的コレクション メソッドを使用して、リストまたはマップを同期バージョンに変換できます: http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collections.html#synchronizedList(java.util 。リスト)
一般に、通常、リストまたはマップへの個々の呼び出し以上のものをロックする必要があります。
Collection 自体をスレッドセーフにする必要があるのは、次の場合だけだと思います。
これらはすべて、おそらく設計上は悪い考えです。
より良いアプローチは、コレクション自体をプライベートまたは保護し、同期されたメソッドを介してアクセスすることです。静的メンバーの場合、それを行う必要がある場合は、Singleton の方が適しています。