# primitive Datentypen threadsicher?



## obscuri (16. Feb 2011)

Hi Leute!

Mal ne kurze Frage: Ist der Zugriff auf primitive Datentypen threadsafe oder muss ich das synchronisieren?
Genauer geht es eigentlich nur um eine boolean Variable. Die steht eben in dem einen Thread in der großen while Schleife:

while(!stop){
	//do stuff
}

Wenn dieser Thread aufhören soll, setzt der andere Thread dann die Variable stop auf true und der andere Thread kann die Schleife dann verlassen und wird dann beendet. Jetzt könnte es ja sein, dass genau in dem Moment der eine Thread die Variable stop schreiben will, während der andere sie lesen will. Ist das automatisch synchronisiert oder kommt es da zu Konflikten ? 
synchronized kann ich auf primitive Datentypen ja nicht anwenden. 

Mir ist wohl klar, dass sowas wie i++; nicht synchronisiert ist, denn wenn mans ausschreibt zu i = i + 1; sieht man ja, dass i erst gelesen werden muss, dann wird 1 addiert und dann erst wird geschreiben. Wenn i jetzt zwischen dem Lesen und dem Schreiben nach der Addition in einem anderen Thread verändert wird, wird dann quasi etwas Falsches in i geschrieben. Aber das meine ich mit meiner Frage auch nicht. 

Es kann nicht sein, dass genau im gleichen Moment ein primitiver Datentyp gelesen und geschrieben wird, oder ?


----------



## T_O_B_E_E (16. Feb 2011)

obscuri hat gesagt.:


> Es kann nicht sein, dass genau im gleichen Moment ein primitiver Datentyp gelesen und geschrieben wird, oder ?



Nein, das geht nicht. Je nachdem welcher Thread intern an der Reihe ist, wird die "stop" Variable geändert oder nicht. Die while Schleife läuft dann entsprechend bis zur nächsten Abfrage der Bedingung.


----------



## maki (16. Feb 2011)

Trotzdem muss in irgendeiner Art und Weise synchronisiert werden, in diesem Falle bietet sich [c]volatile[/c] an.

AngelikaLanger.com - Details zu volatile-Variablen - Angelika Langer Training/Consulting


----------



## tuxedo (16. Feb 2011)

T_O_B_E_E hat gesagt.:


> > Es kann nicht sein, dass genau im gleichen Moment ein primitiver Datentyp gelesen und geschrieben wird, oder ?
> 
> 
> 
> Nein, das geht nicht. Je nachdem welcher Thread intern an der Reihe ist, wird die "stop" Variable geändert oder nicht. Die while Schleife läuft dann entsprechend bis zur nächsten Abfrage der Bedingung.



Öhm, das gilt aber nicht für alle primitiven Typen. Ob's für 
	
	
	
	





```
boolean
```
gilt weiß ich nicht.

Zum Thema 
	
	
	
	





```
int
```
 -> InformIT: Java Reference Guide > Java Atomic Operations

Und es gibt noch 
	
	
	
	





```
AtomicBoolean
```
, 
	
	
	
	





```
AtomicInteger
```
, ...

Ergo bin ich mit bei 
	
	
	
	





```
boolean
```
nicht sicher ob das wirklich atomar ist. Hatte auf der anderen Seite damit aber noch nie Probleme (also mit 
	
	
	
	





```
boolean
```
, mit 
	
	
	
	





```
int
```
schon...)

- Alex


----------



## Lumaraf (16. Feb 2011)

Wenn man ein Feld ändert das nicht volatile ist hat man keine Garantie wann ein anderer Thread die Änderung sieht.
Lese- und Schreibzugriffe werden von der CPU gecached. Es kann dadurch durchaus vorkommen das nach dem setzen des booleans die Schleife trotzdem noch weiterläuft und erst irgendwann später abbricht.

Zugriffe auf volatile Felder umgehen den Cache einfach und schreiben direkt in der Arbeitsspeicher btw lesen direkt daraus. Das ist zwar etwas langsamer aber man hat wenigstens die Garantie das andere Thread die Änderungen sofort sehen können.

Mein Empfehlung wäre statt mit einem extra boolean-Feld den Thread über einen interrupt zu beenden.


```
while (!Thread.interrupted()) {
// ...
}
```


----------



## ice-breaker (16. Feb 2011)

maki hat gesagt.:


> Trotzdem muss in irgendeiner Art und Weise synchronisiert werden, in diesem Falle bietet sich [c]volatile[/c] an.



genauer gesagt muss aber nicht synchronisiert werden, sondern es muss die Sichtbarkeit für einen anderen Thread gewährleistet werden.
Wird in dem Vortrag glaube ich aber auch angesprochen, der ist ein ziemlich guter Einstieg in das Thema.



tuxedo hat gesagt.:


> Öhm, das gilt aber nicht für alle primitiven Typen. Ob's für
> 
> 
> 
> ...


bis auf long, float und double ist es gewährleistet (atomares Schreiben und lesen, aber nicht die Sichtbarkeit !)
Man sollte aber nicht vergessen, dass dies nicht für Operationen wie Inkrementieren usw. gilt, da dies mehrere Operationen sind (lesen, addieren und schreiben)


----------



## Andi_CH (17. Feb 2011)

Vor Kurzem war hier eine Diskussion genau zu dem Thema, aber ich finde es auf die Schnelle auch nicht.
Eigentlich wurde es schon gesagt, aber ich formuliere es IMO etwas deutliher (sagen wir mal "anders"  )

Das Problem ist weniger die Synchronisation (Da ein Thread nur schreibt und der Andere nur liest ist das sowieso nicht wirklich ein Problem) sondern die Tatsache dass z.B. auf Mulitcoremaschinen die Variable stop für den einen Thread als Kopie angelegt werden kann - das heisst es kann sie doppelt oder mehrfach geben.

Volatile zwingt die VM dazu die Variable wirklich nur einmal zu halten.


----------



## xehpuk (17. Feb 2011)

ice-breaker hat gesagt.:


> bis auf long, float und double ist es gewährleistet (atomares Schreiben und lesen, aber nicht die Sichtbarkeit !)


Da bitte einmal 
	
	
	
	





```
float
```
 streichen.


----------



## ice-breaker (17. Feb 2011)

xehpuk hat gesagt.:


> Da bitte einmal
> 
> 
> 
> ...



argh hast Recht, float hat ja auch nur 32 Bit


----------



## obscuri (18. Feb 2011)

Super! Danke für die Antworten! 
Also ums nochmal zusammenzufassen: Zugriffe auf boolean sind atomar und damit kann es nicht sein, dass mehrere Threads genau zur gleichen Zeit auf diese Variable zugreifen. Gleiches gilt auch für alle anderen primtiven Datentypen außer long und double. 
Um die Sichtbarkeit muss ich mich noch selber kümmern imdem ich z.b. die boolean-Variable mit volatile kennzeichne und dann dürfte nichts schiefgehen.

Richtig so?


----------



## Andi_CH (18. Feb 2011)

So sehe ich das auch


----------



## Landei (18. Feb 2011)

Für _Objekte_ sollte man sich das mal durchlesen: Double-checked locking - Wikipedia, the free encyclopedia


----------



## Sonecc (18. Feb 2011)

muss ich meinen üblichen Danke-System Spruch bringen? sollte doch inzwischen jeder kennen


----------



## Andi_CH (18. Feb 2011)

Kannst auch auf den Danke-Knopf klicken


----------

