Moien
Wo wird bei folgendem Code i gespeichert ? Heap (nicht Threadsafe) oder Stack (Threadsafe) ?
public void test(){
int i = 0;
...
}
Danke
Moien
Wo wird bei folgendem Code i gespeichert ? Heap (nicht Threadsafe) oder Stack (Threadsafe) ?
public void test(){
int i = 0;
...
}
Danke
Stack! owT
.
Morgen,
es gibt im groĂźen und ganzen nur Zwei Arten von Variablen. Methodenvariablen und Klassenvariablen. Methoden Variablen werden im Stack gespeichert und Klassenvariablen immer im Heap, jedoch ist zu beachten, dass keine Objekte selbst an methoden ĂĽbergeben werden, sondern immer nur Referenzen und da durch ist jede Art von Object immer im Heap gespeichert.
LG Matthias
[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]
Moien
es gibt im groĂźen und ganzen nur Zwei Arten von Variablen.
Methodenvariablen und Klassenvariablen.
Ja, das war schon klar. Es ging mir mehr drum ob java das genauso tut wie C/C++ und alle anderen auch oder ob die da wiedermal was spezielles verbaut haben. Mir fliegt nämlich ein 500k LOC Programm um die Ohren sobald ich vor so einer Methode das synchronized wegnehme. In der Methode werden keine Klassenvariablen verändert und nur eine Methodenvariable geschrieben. Die Objekte werden im Multithread-Teil gar nicht geändert. Es werden auch keine anderen veränderden Methoden aufgerufen (Math.max/sin & Co mal ausgenommen).
Ich muss mir das Zeug nochmal genauer unterm debugger ankucken.
cu
hallo
kannst du mal das betreffende codestück vollständig posten? du hast nämlich weiter unten geschrieben, dass die methode nur mit lokalen variablen (methodenvariablen) arbeitet - was mir etwas seltsam vorkommt. irgendwie muss die methode ja mit dem objekt interagieren.
was man auch leicht vergisst: java unterscheidet zwischen sogenannten primitiven datentypen und datentypen, die von der basisklasse „object“ abgeleitet sind. primitive datentypen sind int, long, float etc. strings und arrays gehören zu den „objects“.
java kennt zwar keine pointer, trotzdem hantiert man eigentlich nie direkt mit objekten sondern hat immer nur eine object-reference - im prinzip die speicheradresse des objekts (ok, ist intern etwas komplizierter, ist aber hier egal).
daher kommen wir zu:
objektinstanzen liegen immer am heap
objektvariablen (member) gehören direkt zum objekt und liegen daher auch am heap
methodenvariblen zu primitiven datentypen liegen immer am stack
bei methodenvariablen zu objekt-datentypen liegt die objektreferenz am stack, das objekt selbst aber am heap
dazu gibt es dann noch statische variablen, die immer im kontext der klasse selbst gespeichert sind. die funktionieren etwas anders - sie liegen im klassenspeicher - je nach implementierung durch die javavm meist am heap, aber in einem speziell reservierten bereich.
wenn du also eine methode hast, die ausschlieĂźlich mit methodenvariablen arbeitet (also weder input noch output hat), dann ist sie automatisch threadsafe - kann also andere threads nicht beeinflussen, da alles am stack liegt. allerdings hat so eine methode auch wenig sinn - ausser rechenzeit verbraten, wird die wenig tun.
hat die methode parameter bzw. einen returnwert mit primitiven datentypen ist das auch so - liegt alles am stack und implizit threadsafe.
hat die methode parameter bzw. einen returnwert mit objekt-datentypen, dann liegt nur die objektreferenz am stack. das objekt selbst ist am heap. in einer multithreaded-umgebung musst du jetzt bereits extrem aufpassen. wird leider immer wieder gerne übersehen…
verwendest du objektvariablen (member) ist es sowieso klar, dass du explizit threadsafe programmieren musst, um nicht in teufels kĂĽche zu kommen.
zur verdeutlichung:
public class Daten {
private int a = 0;
private int b = 0;
public void setA(int value) {
a = value ;
}
public void setB(int value) {
b = value ;
}
public int getA() {
return a ;
}
public int getB() {
return b ;
}
}
public class Test {
public static void main(String[] args) {
// das "Daten" objekt liegt am heap, die Referenz x am stack
Daten x = new Daten() ;
x.setA ( 1 );
x.setB ( 2 );
// die referenz x wird per wert ĂĽbergeben, d.h. kopiert
swap(x);
// x.getA() liefert 2
// x.getB() liefert 1
}
private static void swap(Daten data) {
// data ist zwar eine kopie von x, beide referenzen zeigen
// aber auf das selbe "Daten" objekt!
// ==\> data ist zwar eine methodenvariable, die am stack liegt,
// die set- und get-methoden manipulieren aber das objekt am heap
int tmp = data.getA();
data.setA(data.getB());
data.setB(tmp);
}
}
das ganze mal als absolutes primitiv-beispiel. wird die swap-methode jetzt in einer multithreaded-umgebung aufgerufen, kommt es zwangsläufig zu massiven problemen: ohne einem synchronized-block kann es passieren, da zwei threads gleichzeitig die selbe methode mit dem selben datenobjekt im hintergrund aufrufen. es kann also sein, dass der scheduler der javavm die einzelnen methodenaufrufen jeweils so ausführt, dass im endeffekt die methoden getA und getB den selben wert zurückliefern.
Thread 1 Thread 2 data.A data.B tmp1 tmp2
---------------------------- -------------------------------- ------ ------ ---- ----
int tmp = data.getA() 1 2 1 0
data.setA(data.getB()) 2 2 1 0
---------
int tmp = data.getA() 2 2 1 2
data.setA(data.getB()) 2 2 1 2
---------
data.setB(tmp) 2 1 1 2
---------
data.setB(tmp) 2 2 1 2
wenn du das ganze in ein synchronized(data) {} packst, wird das ganze threadsafe, dafĂĽr auch etwas langsamer.
ist leider nicht so ganz einfach…
lg
erwin
Moien
Hat sich gerade erledigt … Kumpel hat bei einem anderen Thread Mist gebaut. Dieser mir unbekannte Thread macht einen Abgleich der lokalen Objecte mit denen vom Server. Der sollte eigentlich vorher unsere Daten-Objecte per Mutex sperren. Tat er aber nicht. Wenn der Abgleich in meine Rechnung fällt macht es bei mir ganz übel BOOM.
kannst du mal das betreffende codestück vollständig posten?
Leider nicht, da hätte mein Chef was gegen.
du
hast nämlich weiter unten geschrieben, dass die methode nur
mit lokalen variablen (methodenvariablen) arbeitet - was mir
etwas seltsam vorkommt. irgendwie muss die methode ja mit dem
objekt interagieren.
Es werden keine Klassenvariablen verändert. Aber werden aber jede Menge auslesen. Es geht drum 2 Objekte zu vergleichen. Dazu werden einige Abweichungen (geomentrischer Abstand, Winkel, Farbunterschiede…) bestimmt und in einer Methodenvariable summiert.
ist leider nicht so ganz einfach…
Mir gehen Threads sonst eigentlich leicht von der Hand. Aber nach einem unbekannten, schreibenden Thread zu suchen ist mir nicht in den Sinn gekommen. Pech gehabt und 2 Tage sinnfrei verbraten.
Danke.