17. januar 2008 - 14:17Der er
15 kommentarer og 1 løsning
brug af synchronized
Hi,
public ArrayList<TestClass> testClasses = new ArrayList();
så har jeg en methode, som fjerner values ud af denne ArrayList public removeElems() { synchronized( this.testClasses ) { // fjern elementer } }
Jeg har givet en extern Thread mulighed for at få fat i data fra testClasses. Denne externe methode skal gå igennem alle elementer og finde alle elementer som opfylder bestemte ting. /* i en anden Thread */ public findElems() { for ( int i=0; i<this.sourceObj.testClasses.size(); i++ ) { if (...) { ... } } return ... }
denne methode er ikke fyldt med synchronized. der er mange Threads som vil kalde denne methode. og hvis der hver gang skal blockeres hele ArrayListen, tager det lang tid for at få fat i data'erne.
Mit spørgsmål er: Hvis methoden removeElems() bliver udført. Blockerer den så også de externe methoder som ikke arbejder med synchronized?
Og det derfor man kun skal bruge get- og set-metoder, og ikke referere elementer direkte.
Hvis du synes det går for langsomt, så tænk på de fejl der en gang imellem vil opstå, hvis du ikke drysser en passende mængde synchronized ud over det hele. Så vil jeg hellere at det virker, og er langsomt, end at det næsten virker, men er hurtigt ;)
Tænk også en tand længere:
i = obj.findpos(....); // en anden tråd ændrer obj obj.erstat(i,...);
Problemet med return inde i synchronized er det er et uklart program flow.
Problemet med synchronized paa return varedi af metode er at funktionaliteten aendrer sig hvis den metode aendrer sig.
Overvej 3 forskellige getArrayList implementationer: - en som returnerer en instans variabel - en som returnerer en clone af en instans variabel - en som returnerer en class variabel
Du kan jo overveje om den simple løsning er et godt startpunkt:
1) Alt i klassen er i privat, bortset fra: 2) Alle public metoder er synchronized, herunder get- og set. 3) Beregninger der ikke tåler afbrydelser ligger også i public metoder i klassen.
Det garanterer ikke at alt er uden problemer, men det er lige at gå til.
Og helt generelt vil jeg anbefale at du skjuler for dem, der kigger på din klasse udefra, at du bruger en ArrayList. Din klasse skal have sin egen funktionalitet, uanset hvilken måde du vælger at implementere den på.
er det klogt at bruge synchronized på en String? Strings er jo immutable.
public void getABC() { return this.abcString; } eller public void getABC() { String abcString = null; synchronized( this ) { abcString = this.abcString; } return abcString; } eller public void getABC() { String abcString = null; synchronized( this ) { abcString = new String( this.abcString ); } return abcString; }
hvilken methode er hos String den bedste - og vilken er generelt hos objekter (som ikke er immutable) den bedste? Eller er der en bedre løsning end en af de tre?
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.