2013-07-04 16 views
7

Sto lavorando a un gioco Android e ho notato che dal momento che onTouchEvent viene eseguito sul thread dell'interfaccia utente e i metodi di aggiornamento/rendering vengono eseguiti da thread separati, entrambi aggiornano uno ArrayList che contiene le entità. Quindi, ovviamente, entrano in conflitto se cambiano la lista allo stesso tempo.Modifica da ArrayList a Vector

Ho letto che la classe Vector viene utilizzata esattamente allo stesso modo di ArrayList con la sola differenza che Vector è sincronizzato, in modo che non entrino in conflitto. È vero? in tal caso, ha qualche problema di prestazioni o qualcosa di cui dovrei preoccuparmi? Non ho mai usato la classe Vector prima.

EDIT: quello che in realtà intendevo era il cambiamento dal

ArrayList<Obj> list = new ArrayList<Obj>();

a

Vector<Obj> list = new Vector<Obj>()

Ma, come dicono le risposte, Vector non è raccomandato per l'uso. La risposta selezionata ha risolto il mio problema.

+2

'VECTOR' è deprecato, quindi non si dovrebbe usare – BackSlash

+0

Tecnicamente non lo è, ma in realtà si tratta di un antico e in funzione del use case un 'List' dal pacchetto' Concurrent' probabilmente andrà meglio. –

+0

Jon Skeet spiega perché non utilizzare Vector qui: http://stackoverflow.com/q/1386275/1065197 –

risposta

9

E 'vecchietto Vector cercare di non utilizzare per Vector invece utilizzare

synchronizedList

Esempio:

list = Collections.synchronizedList(list); 

vettore è considerato obsoleto e sconsigliato leggere Why vector is considerer obsolete?

+0

Questo lo risolve: 'Lista list = Collections.synchronizedList (new ArrayList ());' –

+0

sì, tu capito;) leggi la risposta di Jon Skeet nel link che pubblico, è interessante :) – nachokk

+0

Sì, è piuttosto interessante. In realtà mi ha aiutato un po 'a capire il blocco 'sincronizzato'. Sono un po 'nuovo ad esso (: –

2
List<Foo> list = new Vector<Foo>(new ArrayList<Foo>()); 

dovrebbe funzionare. Entrambe le strutture implementano l'interfaccia Elenco.

Ma come suggerito da altre persone, questo non è raccomandato.

+2

Questo snippet di codice non ha molto senso. Aggiungerebbe gli elementi da un 'ArrayList' vuoto per l'istanza' Vector' vuota. – nif

+1

Per quanto ho capito questo era quello che chiese Christopher Francisco.Il vettore con i dati di ArrayList.Nuovo elenco di array c'è solo una specie di finta – ArturSkowronski

+1

Ti rendi conto che il tuo codice non ha nemmeno un senso logico per cominciare? Inoltre, se vuoi davvero aiutare OP, devi sapere e ** aiutare gli altri a imparare ** che ** Vector non è raccomandato per l'uso **. –

0

Come già menzionato da nachokk, synchonizedList farà il trucco. synchronizedList restituirà un wrapper attorno all'elenco, quindi non viene eseguita alcuna copia.
Lo svantaggio è che solo una chiamata alla lista può essere eseguita alla volta. Due letture nell'elenco saranno sequenziali anche se potrebbero essere eseguite in parallelo. I blocchi sincronizzati significano sempre un piccolo sovraccarico e diminuiscono le prestazioni se vengono chiamati spesso.

Un'altra opzione sarebbe quella di utilizzare una lista concorrente. Ciò significa una copia in primo luogo, ma le prestazioni di accesso potrebbero essere notevolmente migliorate. Se hai molte richieste di lettura (ad esempio per i dipinti), una CopyOnWriteArrayList sarà una buona scelta. Le letture sono quasi veloci come un normale ArrayList e non saranno bloccate. Le scritture nella lista saranno sequenziali e costose, poiché devono copiare l'intero array.
Un altro punto utile per CoWArrayList è che è possibile eseguire l'iterazione senza rilevare ConcurrentModificationException. L'Iterator restituito da iterator() utilizzerà sempre lo stesso array di supporto, anche se l'elenco è stato modificato.

20

Per coloro che hanno a combattere con il codice legacy fare proprio il seguente:

new Vector<Obj>(anyThingWhichImplemntsCollection); 
Problemi correlati