2016-01-01 17 views
7

Durante la lettura di Oracle tutorial su collezioni implementazioni, ho trovato la seguente frase:Vector vs prestazioni SynchronizedList

Se avete bisogno di sincronizzazione, un Vector sarà leggermente più veloce di un ArrayList sincronizzato con Collections.synchronizedList

fonte: List Implementations

ma quando si cerca la differenza tra di loro, molte persone scoraggiano l'utilizzo di Vector e deve essere sostituito da SynchronizedList quando è necessaria la sincronizzazione. Quindi, quale lato ha diritto di essere seguito?

+5

La differenza di prestazioni, se presente, e se esiste ancora dal momento in cui è stato scritto l'articolo, è probabilmente trascurabile. Il vettore dovrebbe essere considerato deprecato. Fai come se non esistesse. Inoltre, Collections.synchronizedList() esprime chiaramente l'intento: dice al lettore: ho bisogno di un elenco sincronizzato qui. Mentre il nuovo Vector dice al lettore: questo deve essere stato scritto anni fa, o da un programmatore che ha imparato Java 17 anni fa e non è mai stato aggiornato. –

+0

@JBNizet C'è qualche esempio che mostra come Vector non è adatto per la sincronizzazione e SynchronizedList sta facendo il lavoro meglio di così, perché quando ho guardato dentro i loro codici entrambi usano blocchi/metodi sincronizzati. –

+2

Non è quello sincronizzato e l'altro no. Non l'ho detto Vector è precedente all'appuntamento dell'API delle raccolte, porta un sacco di metodi obsoleti e viene sostituito da ArrayList e Collections.synchronizedList (arrayList).Se non è ancora ufficialmente deprecato, è probabilmente perché è ancora usato nelle API pubbliche di altre vecchie classi del JDK. Ma dovresti considerarlo come tale. –

risposta

0

Vector è una vecchia API, ovviamente. Nessuna domanda lì.

Per velocità, potrebbe essere solo perché l'elenco sincronizzato richiede chiamate di metodo aggiuntive per raggiungere e restituire i dati poiché è un "wrapper" in cima a un elenco dopo tutto. Questo è tutto quello che c'è da fare, imho.

0

Quando si utilizza Collections.synchronizedList(new ArrayList<>()) si separano i due dettagli di implementazione. È chiaro come è possibile modificare il modello di archiviazione sottostante da "array based" a, ad es. "Nodi collegati", semplicemente sostituendo new ArrayList con new LinkedList senza modificare la decorazione synchronized.

L'affermazione che Vector "sarà leggermente più veloce" sembra essere basata sul fatto che il suo utilizzo non sopporta una delega tra il wrapper e lo storage sottostante, ma le dichiarazioni derivate sulla prestazione da quello sono state persino contestate dal tempo, quando sono stati introdotti ArrayList e il wrapper synchronizedList.

Si noti che quando si è veramente preoccupati delle prestazioni di un elenco a cui si accede da più thread, si utilizzerà o di queste due alternative. L'idea di rendere sicuro un thread di archiviazione rendendo imperfetti tutti i metodi di accesso synchronized fin dall'inizio. Ogni operazione che comporta l'accesso multiplo all'elenco, ad es. semplici costrutti come if(!list.contains(o)) list.add(o); o iterazione sull'elenco o anche un semplice Collections.swap(list, i, j); richiedono una sincronizzazione manuale aggiuntiva per funzionare correttamente in una configurazione multi-thread.

Se si pensa che nel corso, vi renderete conto che la maggior parte delle operazioni di una vera e propria applicazione di vita consistono di accesso multiplo e, pertanto, richiederà un'attenta bloccaggio manuale e il fatto che ogni metodo di accesso a basso livello sincronizza inoltre può non solo portare via performance, è anche un travestimento fingendo una sicurezza che non c'è.