Mengapa Java Vector dianggap sebagai kelas warisan, usang atau usang?
Bukankah penggunaannya valid ketika bekerja dengan concurrency?
Dan jika saya tidak ingin menyinkronkan objek secara manual dan hanya ingin menggunakan koleksi thread-safe tanpa perlu membuat salinan baru dari array yang mendasarinya (seperti CopyOnWriteArrayList
halnya), maka apakah boleh digunakan Vector
?
Bagaimana dengan Stack
, yang merupakan subkelas dari Vector
, apa yang harus saya gunakan daripada itu?
Jawaban:
Vector
disinkronkan pada setiap operasi individu. Itu hampir tidak pernah ingin Anda lakukan.Secara umum Anda ingin menyinkronkan seluruh urutan operasi. Menyinkronkan masing-masing operasi kurang aman (jika Anda beralih pada
Vector
, misalnya, Anda masih perlu mengeluarkan kunci untuk menghindari orang lain mengubah koleksi pada saat yang sama, yang akan menyebabkan aConcurrentModificationException
di utas pengulangan) tetapi juga lebih lambat ( mengapa mengambil kunci berulang kali ketika sekali sudah cukup)?Tentu saja, itu juga memiliki penguncian bahkan ketika Anda tidak perlu.
Pada dasarnya, ini adalah pendekatan yang sangat cacat untuk sinkronisasi dalam sebagian besar situasi. Seperti yang ditunjukkan oleh Tuan Brian Henk , Anda dapat menghias koleksi menggunakan panggilan seperti
Collections.synchronizedList
- fakta yangVector
menggabungkan implementasi koleksi "array yang diubah ukurannya" dengan bit "sinkronisasi setiap operasi" adalah contoh lain dari desain yang buruk; pendekatan dekorasi memberikan pemisahan keprihatinan yang lebih bersih.Adapun
Stack
setara - saya akan melihatDeque
/ArrayDeque
mulai dengan.sumber
Vektor adalah bagian dari 1.0 - implementasi asli memiliki dua kelemahan:
1. Penamaan: vektor benar-benar hanya daftar yang dapat diakses sebagai array, sehingga seharusnya dipanggil
ArrayList
(yang merupakan pengganti Java 1.2 Collections untukVector
).2. Concurrency: Semua
get()
,set()
metode yangsynchronized
, sehingga Anda tidak dapat memiliki berbutir halus kontrol atas sinkronisasi.Tidak ada banyak perbedaan antara
ArrayList
danVector
, tetapi Anda harus menggunakannyaArrayList
.Dari dokumen API.
sumber
ArrayList
,LinkedList
, dll, yang semuanya menerapkan antarmukaList
, jadi jika Anda ingin memanfaatkanList
metode tanpa harus mengetahui apa yang mendasari pelaksanaan sebenarnya Anda hanya dapat mengambilList
sebagai parameter untuk metode, dll yang sama berlaku untuk pelaksanaMap
dan seterusnya. Sementara itu, C ++ memang memilikistd::array
kelas, yang hanya pengganti berbasis template untuk array panjang statis C-style.Selain jawaban yang sudah dinyatakan tentang penggunaan Vektor, Vektor juga memiliki banyak metode seputar pencacahan dan pengambilan elemen yang berbeda dari antarmuka Daftar, dan pengembang (terutama mereka yang mempelajari Java sebelum 1.2) dapat cenderung menggunakannya jika mereka berada di kode. Meskipun Pencacahan lebih cepat, mereka tidak memeriksa apakah koleksi telah diubah selama iterasi, yang dapat menyebabkan masalah, dan mengingat bahwa Vector mungkin dipilih untuk sinkronisasi - dengan akses yang hadir dari beberapa utas, ini membuatnya menjadi masalah yang sangat berbahaya. Penggunaan metode ini juga memasangkan banyak kode ke Vector, sehingga tidak akan mudah untuk menggantinya dengan implementasi Daftar yang berbeda.
sumber
Anda dapat menggunakan synchronizedCollection / Daftar metode
java.util.Collection
untuk mendapatkan koleksi benang-aman dari satu non-benang-aman.sumber
java.util.Stack
mewarisi overhead sinkronisasijava.util.Vector
, yang biasanya tidak dibenarkan.Ini mewarisi lebih banyak dari itu. Fakta itu
java.util.Stack extends java.util.Vector
adalah kesalahan dalam desain berorientasi objek. Purist akan mencatat bahwa ia juga menawarkan banyak metode di luar operasi yang secara tradisional dikaitkan dengan stack (yaitu: push, pop, peek, size). Ini juga mungkin untuk melakukansearch
,elementAt
,setElementAt
,remove
, dan banyak operasi random-akses lainnya. Pada dasarnya terserah kepada pengguna untuk menahan diri dari menggunakan operasi non-stackStack
.Untuk alasan kinerja dan desain OOP ini, JavaDoc untuk
java.util.Stack
merekomendasikanArrayDeque
sebagai pengganti alami. (Deque lebih dari sekadar tumpukan, tapi setidaknya itu terbatas untuk memanipulasi kedua ujungnya, daripada menawarkan akses acak ke semuanya.)sumber