717

Java Vectorがレガシークラスと見なされ、廃止または廃止されたのはなぜですか?

並行性を扱う場合、その使用は有効ではありませんか?

また、オブジェクトを手動で同期するのではなく、基になる配列の新しいコピーを作成する必要なしにスレッドセーフなコレクションを使用したい場合は(そうするようにCopyOnWriteArrayList)、使用しても問題ありませVectorんか?

Stackのサブクラスである、はどうですか、Vectorその代わりに何を使用する必要がありますか?

4

5 に答える 5

694

Vector個々の操作ごとに同期します。それはあなたがやりたいことではほとんどありません。

通常、一連の操作全体を同期する必要があります。個々の操作の同期は安全性が低くなります(Vectorたとえば、を反復処理する場合でも、他の誰かが同時にコレクションを変更しないようにロックを解除する必要があります。これによりConcurrentModificationException、反復スレッドでが発生します)。一度だけで十分なのに、なぜ繰り返しロックを解除するのですか?

もちろん、必要がない場合でもロックのオーバーヘッドがあります。

基本的に、これはほとんどの状況で同期するための非常に欠陥のあるアプローチです。ブライアン・ヘンク氏が指摘したように、次のような呼び出しを使用してコレクションを装飾できます。「サイズ変更された配列」コレクションの実装と「すべての操作の同期」ビットの両方Collections.synchronizedListを組み合わせたという事実は、不十分な設計のもう1つの例です。Vector装飾アプローチにより、関心の分離がより明確になります。

同等のものについてはStack-私はDeque/ArrayDequeを最初に見ていきます。

于 2009-09-06T18:07:44.517 に答える
87

ベクターは1.0の一部でした。元の実装には2つの欠点がありました。

1.命名:ベクトルは実際には配列としてアクセスできる単なるリストであるため、呼び出される必要がありますArrayList(これはJava 1.2コレクションの代わりになりますVector)。

2.同時実行性:すべてのget()メソッドset()synchronizedであるため、同期をきめ細かく制御することはできません。

ArrayListとの間に大きな違いはありませんVectorが、を使用する必要がありますArrayList

APIドキュメントから。

Java 2プラットフォームv1.2の時点で、このクラスはListインターフェースを実装するように改良され、Javaコレクションフレームワークのメンバーになりました。新しいコレクションの実装とは異なり、Vectorは同期されます。

于 2009-09-06T18:12:31.793 に答える
42

Vectorの使用に関するすでに述べた回答に加えて、Vectorには、リストインターフェイスとは異なる、列挙と要素の取得に関する多数のメソッドがあり、開発者(特に、1.2より前にJavaを学習した人)は、コード。列挙は高速ですが、反復中にコレクションが変更されたかどうかをチェックしないため、問題が発生する可能性があります。また、複数のスレッドからの付随アクセスにより、Vectorが同期に選択される可能性があるため、これは特に厄介な問題になります。これらのメソッドを使用すると、多くのコードがVectorに結合されるため、別のList実装に置き換えるのは簡単ではありません。

于 2009-09-06T20:53:26.227 に答える
15

でsynchronizedCollection/Listメソッドを使用しjava.util.Collectionて、スレッドセーフでないコレクションからスレッドセーフなコレクションを取得できます。

于 2009-09-06T18:07:36.763 に答える
9

java.util.Stackの同期オーバーヘッドを継承しますがjava.util.Vector、これは通常は正当化されません。

ただし、それ以上のものを継承します。java.util.Stack extends java.util.Vectorそれがオブジェクト指向設計の間違いであるという事実。純粋主義者は、これまでスタックに関連付けられていた操作(つまり、プッシュ、ポップ、ピーク、サイズ)以外にも多くのメソッドを提供することに気付くでしょう。、、、、、およびその他の多くのランダムアクセス操作searchを実行することもできます。基本的に、の非スタック操作の使用を控えるのはユーザーの責任です。elementAtsetElementAtremoveStack

これらのパフォーマンスとOOP設計上の理由から、JavaDocforjava.util.StackArrayDequeは自然な代替として推奨しています。(dequeはスタック以上のものですが、少なくとも、すべてへのランダムアクセスを提供するのではなく、両端を操作することに制限されています。)

于 2016-02-12T21:04:52.770 に答える