Java Vectorがレガシークラスと見なされ、廃止または廃止されたのはなぜですか?
並行性を扱う場合、その使用は有効ではありませんか?
また、オブジェクトを手動で同期するのではなく、基になる配列の新しいコピーを作成する必要なしにスレッドセーフなコレクションを使用したい場合は(そうするようにCopyOnWriteArrayList
)、使用しても問題ありませVector
んか?
Stack
のサブクラスである、はどうですか、Vector
その代わりに何を使用する必要がありますか?
Java Vectorがレガシークラスと見なされ、廃止または廃止されたのはなぜですか?
並行性を扱う場合、その使用は有効ではありませんか?
また、オブジェクトを手動で同期するのではなく、基になる配列の新しいコピーを作成する必要なしにスレッドセーフなコレクションを使用したい場合は(そうするようにCopyOnWriteArrayList
)、使用しても問題ありませVector
んか?
Stack
のサブクラスである、はどうですか、Vector
その代わりに何を使用する必要がありますか?
Vector
個々の操作ごとに同期します。それはあなたがやりたいことではほとんどありません。
通常、一連の操作全体を同期する必要があります。個々の操作の同期は安全性が低くなります(Vector
たとえば、を反復処理する場合でも、他の誰かが同時にコレクションを変更しないようにロックを解除する必要があります。これによりConcurrentModificationException
、反復スレッドでが発生します)。一度だけで十分なのに、なぜ繰り返しロックを解除するのですか?
もちろん、必要がない場合でもロックのオーバーヘッドがあります。
基本的に、これはほとんどの状況で同期するための非常に欠陥のあるアプローチです。ブライアン・ヘンク氏が指摘したように、次のような呼び出しを使用してコレクションを装飾できます。「サイズ変更された配列」コレクションの実装と「すべての操作の同期」ビットの両方Collections.synchronizedList
を組み合わせたという事実は、不十分な設計のもう1つの例です。Vector
装飾アプローチにより、関心の分離がより明確になります。
同等のものについてはStack
-私はDeque
/ArrayDeque
を最初に見ていきます。
ベクターは1.0の一部でした。元の実装には2つの欠点がありました。
1.命名:ベクトルは実際には配列としてアクセスできる単なるリストであるため、呼び出される必要がありますArrayList
(これはJava 1.2コレクションの代わりになりますVector
)。
2.同時実行性:すべてのget()
メソッドset()
はsynchronized
であるため、同期をきめ細かく制御することはできません。
ArrayList
との間に大きな違いはありませんVector
が、を使用する必要がありますArrayList
。
APIドキュメントから。
Java 2プラットフォームv1.2の時点で、このクラスはListインターフェースを実装するように改良され、Javaコレクションフレームワークのメンバーになりました。新しいコレクションの実装とは異なり、Vectorは同期されます。
Vectorの使用に関するすでに述べた回答に加えて、Vectorには、リストインターフェイスとは異なる、列挙と要素の取得に関する多数のメソッドがあり、開発者(特に、1.2より前にJavaを学習した人)は、コード。列挙は高速ですが、反復中にコレクションが変更されたかどうかをチェックしないため、問題が発生する可能性があります。また、複数のスレッドからの付随アクセスにより、Vectorが同期に選択される可能性があるため、これは特に厄介な問題になります。これらのメソッドを使用すると、多くのコードがVectorに結合されるため、別のList実装に置き換えるのは簡単ではありません。
でsynchronizedCollection/Listメソッドを使用しjava.util.Collection
て、スレッドセーフでないコレクションからスレッドセーフなコレクションを取得できます。
java.util.Stack
の同期オーバーヘッドを継承しますがjava.util.Vector
、これは通常は正当化されません。
ただし、それ以上のものを継承します。java.util.Stack extends java.util.Vector
それがオブジェクト指向設計の間違いであるという事実。純粋主義者は、これまでスタックに関連付けられていた操作(つまり、プッシュ、ポップ、ピーク、サイズ)以外にも多くのメソッドを提供することに気付くでしょう。、、、、、およびその他の多くのランダムアクセス操作search
を実行することもできます。基本的に、の非スタック操作の使用を控えるのはユーザーの責任です。elementAt
setElementAt
remove
Stack
これらのパフォーマンスとOOP設計上の理由から、JavaDocforjava.util.Stack
ArrayDeque
は自然な代替として推奨しています。(dequeはスタック以上のものですが、少なくとも、すべてへのランダムアクセスを提供するのではなく、両端を操作することに制限されています。)