|
| ArrayList vs Vector Fra : dejan |
Dato : 10-12-01 03:08 |
|
Hej, dette er muligvis et simpelt spørgsmål: hvad er den konkrete forskel
mellem ArrayList og Vector. Vector har de samme metoder som ArrayList og så
nogle flere.
I API dokumentationen står der at ArrayList er "not- synchronized" mens
Vector er "synchronized". Men hvad vil det egentlig sige? Jeg ved at der har
noget med synkroniseringen at gøre, hvis man f.eks. har flere tråde der har
adgang til et ArrayList objekt.
Men har en ArrayList nogle konkrete fordele frem for Vector, eller rettere
sagt: er der nogen der kan eksemplificere i hvilke situationer er det bedre
at bruge ArrayList frem for Vector?
mvh Dejan
| |
Dennis Thrysøe (10-12-2001)
| Kommentar Fra : Dennis Thrysøe |
Dato : 10-12-01 08:13 |
|
dejan wrote:
> Hej, dette er muligvis et simpelt spørgsmål: hvad er den konkrete forskel
> mellem ArrayList og Vector. Vector har de samme metoder som ArrayList og så
> nogle flere.
ArrayList indgår i det 'nye' Collection framework og kan bruges i masser
af sammenhænge med de andre Collections.
> I API dokumentationen står der at ArrayList er "not- synchronized" mens
> Vector er "synchronized". Men hvad vil det egentlig sige? Jeg ved at der har
> noget med synkroniseringen at gøre, hvis man f.eks. har flere tråde der har
> adgang til et ArrayList objekt.
Der kan kune være en tråd der arbejder med en Vector ad gangen. Det
betyder en ikke alt for god performance. Men til gengæld skal man selv
sørge for synkroniserng af en ArrayList, hvis påkrævet. (Her kan
java.util.Collections klassen nok hjælpe).
> Men har en ArrayList nogle konkrete fordele frem for Vector, eller rettere
> sagt: er der nogen der kan eksemplificere i hvilke situationer er det bedre
> at bruge ArrayList frem for Vector?
Altid ;)
ArrayList passer bedre ind med de andre Collections (Sets, Maps,
Sortering osv.). Det kan i nogen sammenhænge være meget dyrt med den
totale synkronisering der er indbygget i Vector.
Desuden har jeg ladt mig fortælle, at der er en enkelt eller to
optimeringer i ArrayList. Men jeg ved ikke om det er noget særligt.
-dennis
| |
Morten Primdahl (10-12-2001)
| Kommentar Fra : Morten Primdahl |
Dato : 10-12-01 15:04 |
|
Dennis Thrysøe wrote:
> dejan wrote:
>
>> Hej, dette er muligvis et simpelt spørgsmål: hvad er den konkrete forskel
>> mellem ArrayList og Vector. Vector har de samme metoder som ArrayList
>> og så
>> nogle flere.
>
> ArrayList indgår i det 'nye' Collection framework og kan bruges i masser
> af sammenhænge med de andre Collections.
Vector implementerer de samme interfaces som ArrayList, så funktionelt
er de meget ens.
>> I API dokumentationen står der at ArrayList er "not- synchronized" mens
>> Vector er "synchronized". Men hvad vil det egentlig sige? Jeg ved at
>> der har
>> noget med synkroniseringen at gøre, hvis man f.eks. har flere tråde
>> der har
>> adgang til et ArrayList objekt.
>
> Der kan kune være en tråd der arbejder med en Vector ad gangen. Det
> betyder en ikke alt for god performance. Men til gengæld skal man selv
> sørge for synkroniserng af en ArrayList, hvis påkrævet. (Her kan
> java.util.Collections klassen nok hjælpe).
Dit valg kommer an på dine intentioner med data strukturen og ikke
mindst de omgivelser den befinder sig i. Grunden til at ArrayList og
HashMap mv. overhovedet kom med er, at folk selv skal have muligheden
for at synkronisere som det passer dem.
Jeg forstår ikke helt dine intentioner med java.util.Collections mht.
synkronisering?
>> Men har en ArrayList nogle konkrete fordele frem for Vector, eller
>> rettere
>> sagt: er der nogen der kan eksemplificere i hvilke situationer er det
>> bedre
>> at bruge ArrayList frem for Vector?
>
> Altid ;)
>
> ArrayList passer bedre ind med de andre Collections (Sets, Maps,
> Sortering osv.). Det kan i nogen sammenhænge være meget dyrt med den
> totale synkronisering der er indbygget i Vector.
Som skrevet ovenfor, afhænger det igen af dit formål - der er ikke noget
der "passer bedre ind". Ja, du får et lille performance hit når du
bruger synchronized - men i et flertrådet miljø vil man sikkert
værdsætte den automatiske synkronisering i en Vector?
Mvh Morten
--
Morten Primdahl Caput A/S Phone +45 70 12 24 42
System Integrator Nygade 6 Fax +45 70 11 24 42
morten@caput.com DK-1164 Kbh K http://www.caput.com/
| |
Dennis Thrysøe (10-12-2001)
| Kommentar Fra : Dennis Thrysøe |
Dato : 10-12-01 16:57 |
|
Morten Primdahl wrote:
> Dennis Thrysøe wrote:
>
>> dejan wrote:
>>
>>> Hej, dette er muligvis et simpelt spørgsmål: hvad er den konkrete
>>> forskel
>>> mellem ArrayList og Vector. Vector har de samme metoder som ArrayList
>>> og så
>>> nogle flere.
>>
>>
>> ArrayList indgår i det 'nye' Collection framework og kan bruges i
>> masser af sammenhænge med de andre Collections.
>
>
>
> Vector implementerer de samme interfaces som ArrayList, så funktionelt
> er de meget ens.
Hmm. Det havde jeg ikke bemærket.
>>> I API dokumentationen står der at ArrayList er "not- synchronized" mens
>>> Vector er "synchronized". Men hvad vil det egentlig sige? Jeg ved at
>>> der har
>>> noget med synkroniseringen at gøre, hvis man f.eks. har flere tråde
>>> der har
>>> adgang til et ArrayList objekt.
>>
>>
>> Der kan kune være en tråd der arbejder med en Vector ad gangen. Det
>> betyder en ikke alt for god performance. Men til gengæld skal man selv
>> sørge for synkroniserng af en ArrayList, hvis påkrævet. (Her kan
>> java.util.Collections klassen nok hjælpe).
>
>
> Dit valg kommer an på dine intentioner med data strukturen og ikke
> mindst de omgivelser den befinder sig i. Grunden til at ArrayList og
> HashMap mv. overhovedet kom med er, at folk selv skal have muligheden
> for at synkronisere som det passer dem.
Helt enig. Men typisk (min påstand) er det ikke smart at synkronisere på
instans.
> Jeg forstår ikke helt dine intentioner med java.util.Collections mht.
> synkronisering?
På den klasse kan man få fat i nogle synkrniserede wrapper, hvis man
skulle være til den slags.
>>> Men har en ArrayList nogle konkrete fordele frem for Vector, eller
>>> rettere
>>> sagt: er der nogen der kan eksemplificere i hvilke situationer er det
>>> bedre
>>> at bruge ArrayList frem for Vector?
>>
>>
>> Altid ;)
>
>
>>
>> ArrayList passer bedre ind med de andre Collections (Sets, Maps,
>> Sortering osv.). Det kan i nogen sammenhænge være meget dyrt med den
>> totale synkronisering der er indbygget i Vector.
>
>
>
> Som skrevet ovenfor, afhænger det igen af dit formål - der er ikke noget
> der "passer bedre ind". Ja, du får et lille performance hit når du
> bruger synchronized - men i et flertrådet miljø vil man sikkert
> værdsætte den automatiske synkronisering i en Vector?
Ja muligvis. Hvis man husker at være opmærksom på evt. starvation.
Det med at 'passe bedre ind' er min opfattelse da Vector kom før
Collection frameworket, som der satses på fremover. Det betyder f.eks.
at man kan få Enumerations ud, som ikke er 'fail-fast'.
Så hvis ikke synkronisering spiller ind (enkelt trådet program) ville
jeg bruge ArrayList. Selvom besparelsen på at gå ud og ind af monitorene
er minimal.
Hvis synkrnisering er vigtig ville jeg alligevel vælge ArrayList i de
fleste tilfælde. Det er ofte en fordel at synkronisere på større blokke
end det ene metode kald på Vector.
Hvis ikke ovenstående spiller ind overhovedet er det stort set
ligegyldigt hvad man vælger. Man kunne så inddrage et argument som
bagud-kompabilitet for Vector.
-dennis
| |
Mikkel Bundgaard (10-12-2001)
| Kommentar Fra : Mikkel Bundgaard |
Dato : 10-12-01 17:00 |
|
"Morten Primdahl" <morten@caput.com> wrote in message
news:3C14C0D6.1010604@caput.com...
> Dennis Thrysøe wrote:
>
<SNIP Vector ArrayList og synkronisering>
> > Der kan kune være en tråd der arbejder med en Vector ad
> > gangen. Det betyder en ikke alt for god performance. Men til
> > gengæld skal man selv sørge for synkroniserng af en ArrayList,
> > hvis påkrævet. (Her kan java.util.Collections klassen nok
> > hjælpe).
>
> Dit valg kommer an på dine intentioner med data strukturen og
> ikke mindst de omgivelser den befinder sig i. Grunden til at
> ArrayList og HashMap mv. overhovedet kom med er, at folk selv
> skal have muligheden for at synkronisere som det passer dem.
>
> Jeg forstår ikke helt dine intentioner med java.util.Collections
mht.
> synkronisering?
>
Jeg tror, at han mener, at man kan bruge metoden synchronizedList
til at synkronisere f.eks. en ArrayList.
Fra Javadoc:
public static List synchronizedList(List list)
Returns a synchronized (thread-safe) list backed by the specified
list. In order to guarantee serial access, it is critical that all
access to the backing list is accomplished through the returned
list....
> > ArrayList passer bedre ind med de andre Collections (Sets,
> > Maps, Sortering osv.). Det kan i nogen sammenhænge være
> > meget dyrt med den totale synkronisering der er indbygget i
> > Vector.
>
>
> Som skrevet ovenfor, afhænger det igen af dit formål - der er
> ikke noget der "passer bedre ind". Ja, du får et lille performance
> hit når du bruger synchronized - men i et flertrådet miljø vil man
> sikkert værdsætte den automatiske synkronisering i en Vector?
>
> Mvh Morten
Jeg er lidt uenig her . Det er ikke noget lille performance hit man
får, når man bruger synkroniserede metoder, men det bliver da
løbende bedre for hver JVM . Men det vigtigste er dog, som du
siger, at man selv kan vælge det, der passer til problemet.
--
Mikkel Bundgaard
IT University of Copenhagen
http://officehelp.gone.dk
Codito, Ergo Sum
| |
Jan Oksfeldt Jonasen (10-12-2001)
| Kommentar Fra : Jan Oksfeldt Jonasen |
Dato : 10-12-01 18:43 |
|
Dennis Thrysøe <dt@netnord.dk> wrote:
> ArrayList indgår i det 'nye' Collection framework og kan bruges i masser
> af sammenhænge med de andre Collections.
>
Vector er også blevet forfremmet til at indgå i Collection API'et,
ligeså er Properties.
> Der kan kune være en tråd der arbejder med en Vector ad gangen. Det
> betyder en ikke alt for god performance. Men til gengæld skal man selv
> sørge for synkroniserng af en ArrayList, hvis påkrævet. (Her kan
> java.util.Collections klassen nok hjælpe).
>
Du vil være en modig person hvis du tillod flere tråde at bruge din
ArrayList. Det praktiske iht. den manglende synkronisering ligger når
netop kun én tråd benyttes, hvorved du slipper for unådig spild. En
syncroniseret List fremstilles med f.eks.
List liste = Collections.synchronizedList(new ArrayList());
Til den oprindelige spørger: Forskellen på synkroniseret eller ej ligger
i om flere kan ændre din struktur på samme tid. Med synkronisering
garanteres du, at kun én tråd kan ændre indenfor dennes metode kald.
F.eks. vil du med et kald til List.add(element) være sikker på at dit
element bliver tilføjet korrekt samt listens størrelse forsat er
korrekt. Tilgengæld skal du ikke falde i fælden og tro at det altid kun
vil være samme tråd der modificere listen.
List liste = new Vector();
....
liste.add(objekter i læssevis);
....
for (int i = 0; i < liste.size(); i++)
{
Object mitObject = liste.get(i);
...
}
Ovenstående kan nemt gå galt, da der kan blive tjekket på størrelse af
listen, hvilket i dette tilfælde er synkroniseret og giver dig det
rigtige øjebliksbillede, derefter fjernes det element du "ved" er
tilstede. Det er det bare ikke og en IndexOutOfBoundsException blive
smidt. Grunden ville være at i tiden mellem .size() og .get() har en
anden tråd ændret listen, hvilket ikke er beskyttet af synkronisering,
da løkken er mellem metode kald. Den korrekte metode ville være enten:
syncronized (liste)
{
for (int i = 0; i < liste.size(); i++)
{
Object mitObject = liste.get(i);
...
}
}
Ovenstående ville dog blive rigtigt pænt hvis en java.util.Iterator blev
benyttet i stedet, da man så kunne benytte følgende idiom:
for (Iterator i = liste.iterator; i.hasNext();)
....
--
Mvh/re Jan Jonasen
jonasen (at) it (dot) dk
If I wanted culture, I'd eat yogurt.
| |
Dennis Thrysøe (11-12-2001)
| Kommentar Fra : Dennis Thrysøe |
Dato : 11-12-01 08:33 |
|
Jan Oksfeldt Jonasen wrote:
> Dennis Thrysøe <dt@netnord.dk> wrote:
>
>
>>ArrayList indgår i det 'nye' Collection framework og kan bruges i masser
>>af sammenhænge med de andre Collections.
>>
>>
> Vector er også blevet forfremmet til at indgå i Collection API'et,
> ligeså er Properties.
Ja, men de indeholder stadig lidt - for nogen måske ubetydelige - levn
fra deres fortid.
>>Der kan kune være en tråd der arbejder med en Vector ad gangen. Det
>>betyder en ikke alt for god performance. Men til gengæld skal man selv
>>sørge for synkroniserng af en ArrayList, hvis påkrævet. (Her kan
>>java.util.Collections klassen nok hjælpe).
>>
>>
> Du vil være en modig person hvis du tillod flere tråde at bruge din
> ArrayList. Det praktiske iht. den manglende synkronisering ligger når
> netop kun én tråd benyttes, hvorved du slipper for unådig spild. En
> syncroniseret List fremstilles med f.eks.
> List liste = Collections.synchronizedList(new ArrayList());
Jeg mener ikke det vil være specielt modigt. For det første oplever jeg
tit behov for at lave en større datastruktur der består af flere
Collections mv. (f.eks. ArrayLists). Her vil jeg jo typisk synkronisere
på *hele* denne datastruktur, og ikke hvert eneste Collection.
Desuden er ArrayList også trådsikker til alt andet end 'strukturelle
ændringer'. F.eks. læsninger og erstatninger af allerede eksisterende
elementer er trådsikkert.
-dennis
| |
Jan Oksfeldt Jonasen (12-12-2001)
| Kommentar Fra : Jan Oksfeldt Jonasen |
Dato : 12-12-01 18:57 |
|
Dennis Thrysøe <dt@netnord.dk> wrote:
> Jeg mener ikke det vil være specielt modigt. For det første oplever jeg
> tit behov for at lave en større datastruktur der består af flere
> Collections mv. (f.eks. ArrayLists). Her vil jeg jo typisk synkronisere
> på *hele* denne datastruktur, og ikke hvert eneste Collection.
>
Det er naturligvis en løsning med både livrem og seler, men kan også
være gevaldigt overkill for måske at hente det 3. element i den 10.
liste.
> Desuden er ArrayList også trådsikker til alt andet end 'strukturelle
> ændringer'. F.eks. læsninger og erstatninger af allerede eksisterende
> elementer er trådsikkert.
>
Kiggede i kildekoden til f.eks. ArrayList, følgende er ikke på nogen
måde sikkert:
public Object get(int index) {
RangeCheck(index);
return elementData[index];
}
index kan nemt have ændret sig i mellemtiden f.eks. ved den ligeså tråd
fjenske:
public boolean add(Object o) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = o;
return true;
}
Erstatning er endnu farligere, da både index, size og ikke mindst en del
forhold ved ensureCapacity() kaldet kan ændre sig:
public void add(int index, Object element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
ensureCapacity(size+1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
Samme principper gør sig gældende for andre "nye" Collection
implementationer herunder HashMap og TreeSet. Dette gør bestemt ikke
nogen af klasserne dårlige, og vil man have synkronisering på de enkelte
kald, kan Collections statiske metoder bruges.
--
Mvh/re Jan Jonasen
jonasen (at) it (dot) dk
If I wanted culture, I'd eat yogurt.
| |
Dennis Thrysøe (13-12-2001)
| Kommentar Fra : Dennis Thrysøe |
Dato : 13-12-01 07:39 |
|
Jan Oksfeldt Jonasen wrote:
> Dennis Thrysøe <dt@netnord.dk> wrote:
>
>
>>Jeg mener ikke det vil være specielt modigt. For det første oplever jeg
>>tit behov for at lave en større datastruktur der består af flere
>>Collections mv. (f.eks. ArrayLists). Her vil jeg jo typisk synkronisere
>>på *hele* denne datastruktur, og ikke hvert eneste Collection.
>>
>>
> Det er naturligvis en løsning med både livrem og seler, men kan også
> være gevaldigt overkill for måske at hente det 3. element i den 10.
> liste.
Det var ikke helt det jeg mente. Hvis alle de 10 lister står i forhold
til hinanden og skal opdateres samtidigt, så vil jeg meget gerne
synkronisere samlet.
Hvis ikke de individuelle lister har noget med hinanden at gøre, vil jeg
naturligvis synkronisere på dem individuelt.
>>Desuden er ArrayList også trådsikker til alt andet end 'strukturelle
>>ændringer'. F.eks. læsninger og erstatninger af allerede eksisterende
>>elementer er trådsikkert.
>>
>>
> Kiggede i kildekoden til f.eks. ArrayList, følgende er ikke på nogen
> måde sikkert:
> public Object get(int index) {
> RangeCheck(index);
>
> return elementData[index];
> }
>
> index kan nemt have ændret sig i mellemtiden f.eks. ved den ligeså tråd
> fjenske:
> public boolean add(Object o) {
> ensureCapacity(size + 1); // Increments modCount!!
> elementData[size++] = o;
> return true;
> }
Jeg har ikke kigget i koden. Min kommentar stammer udelukkende fra
javadoc'en. Og i dit ovenstående eksempel sker der også en strukturel
ændring ved at kalde add() som kan ændre på f.eks. RangeCheck() metodens
opførsel.
Men jeg medgiver, at der i langt de fleste tilfælde alligevel ville
skulle synkroniseres for alle metoder, da man typisk både læser og laver
'strukturelle' ændringer hele tiden.
> Erstatning er endnu farligere, da både index, size og ikke mindst en del
> forhold ved ensureCapacity() kaldet kan ændre sig:
>
> public void add(int index, Object element) {
> if (index > size || index < 0)
> throw new IndexOutOfBoundsException(
> "Index: "+index+", Size: "+size);
>
> ensureCapacity(size+1); // Increments modCount!!
> System.arraycopy(elementData, index, elementData, index + 1,
> size - index);
> elementData[index] = element;
> size++;
> }
Det er korrekt. Men igen afhænger det af brug.
Uden at afsløre alt for meget kan jeg godt sige, at vi ikke altid kun
benytter Java's monitors til synkronisering. Ofte gør vi forskel på
læsning og skrivning, således at enten kan være flere læsende tråde i en
monitor eller en skrivende.
Med denne mekanisme kan man udnytte at læsning fra f.eks en ArrayList
ikke behøver at være synkroniseret. For skrivningens vedkommende er det
også vores eget framework - frem for ArrayList - der står for
synkrniseringen. Så er der sikkerhed for at der kun er en tråd af gangen
der kan ændre på den komplekse datastruktur, som vores ArrayList indgår i.
> Samme principper gør sig gældende for andre "nye" Collection
> implementationer herunder HashMap og TreeSet. Dette gør bestemt ikke
> nogen af klasserne dårlige, og vil man have synkronisering på de enkelte
> kald, kan Collections statiske metoder bruges.
Helt enig.
-dennis
| |
|
|