# Thread beenden



## Sunchezz (18. Jan 2011)

Halli hallo,

ich möchte einen laufenden Thread beenden, habe aber keine Ahnung was ich falsch mache.
Die ganzen sinnvoll benannten Methoden die dafür in Frage kämen aus der API sind ja offensichtlich deprecated.

Nach dem ich mich informiert habe, war für mich der nächste sinnvolle Versuch das vorhandene Threadobjekt zu überschreiben:

```
Thread workThread = new Thread() {
.....
}
...
workThread.run();
....


workThread = null; // bzw. new Thread() {
```

allerdings hat das nur zur Folge, das der Thread anscheinend vordergründig nicht mehr läuft, also es keine aktualisierungen mehr auf der GUI gibt, das aber auch nur kurz.

Nach einer Weile wird der Thread weiter ausgeführt, ich habe mich noch nicht damit beschäftigt ob der Thread komplett ausgeführt wird, oder in der "Pause" wirklich keine arbeit im Thread verrichtet wird, da es mir eh egal ist.
Er soll ja eigentlich garnichts mehr tun.

Ach ja, zur weiteren Info, es geht um einen Abbrechen-Button der einen Arbeitsthread unterbrechen soll, welcher mehrere Daten überprüft was eine Weile dauern kann.

Ich hoffe es ist klar geworden worums geht.

Vielen Dank schonmal!


----------



## KrokoDiehl (18. Jan 2011)

Einen Thread zu 'killen' ist auch eher eine unschöne Art. Ein Thread ist immer dann zuende, wenn seine run()-Methode durchgelaufen ist, d.h. du musst dafür sorgen, dass er diese zum Ende kommt. Das könnte z.B. wie folgt aussehen:


```
public class MyThread extends Thread
{
    private boolean arbeite = true;

    public void hoerAufZuArbeiten()
    {
        arbeite = false;
    }    

    public void run()
    {
        while (arbeite)
        {    
            // ...
        }
    }
}
```


----------



## FArt (18. Jan 2011)

KrokoDiehl hat gesagt.:


> Einen Thread zu 'killen' ist auch eher eine unschöne Art. Ein Thread ist immer dann zuende, wenn seine run()-Methode durchgelaufen ist, d.h. du musst dafür sorgen, dass er diese zum Ende kommt. Das könnte z.B. wie folgt aussehen:
> 
> 
> ```
> ...



Wie so oft bei diesem einfachen Beispiel wurde vergessen den Zugriff auf das Flag zu synchronisiern.

@TS
Nimm keinen Thread sondern etwas aus dem Package java.util.concurrent, z.B. Executors (Java 2 Platform SE 5.0). Damit mach man in der Regel weniger Fehler...


----------



## Gastredner (18. Jan 2011)

FArt hat gesagt.:


> Wie so oft bei diesem einfachen Beispiel wurde vergessen den Zugriff auf das Flag zu synchronisiern.


Wieso sollte man bei diesem Beispiel auch synchronisieren? Auf die Variable kann doch immer nur durch einen Thread zugegriffen werden, oder sehe ich das falsch?


----------



## FArt (18. Jan 2011)

Gastredner hat gesagt.:


> Wieso sollte man bei diesem Beispiel auch synchronisieren? Auf die Variable kann doch immer nur durch einen Thread zugegriffen werden, oder sehe ich das falsch?



Alleine hier greifen schon zwei Threads darauf zu: der Thread der gerade die Arbeit macht und der Thread, der von außen das Flag setzt.

Suche mal im Forum und im Internet... ist ein Standardfehler der schon bis zum Erbrechen diskutiert wurde... Stichwort ist z.B. "volatile".


----------



## SlaterB (18. Jan 2011)

was kann denn bei einem einzelnen boolean schiefgehen?


----------



## Andi_CH (18. Jan 2011)

FArt hat gesagt.:


> Wie so oft bei diesem einfachen Beispiel wurde vergessen den Zugriff auf das Flag zu synchronisiern.



Das stimmt zwar, aber was ist die schlimmste aller möglichen Folgen? Der Thread macht einen Loop zu viel und das ist wirklich nicht tragisch.

Wenn der Thread so X-1000 mal pro Sekunde abfragt ob er weiter arbeiten soll, ist wohl der Synchronisationsaufwand nicht ganz zu vernachlässigen und hier ist ja ganz klar dass einer nur liest und der andere nur schreibt, also ist das unkritisch.

Ein anderes Thema wäre ein Konstrukt wie das Folgende:
(Bitte nicht über den Sinn oder Unsinn diskutieren  - 
	
	
	
	





```
weiterArbeiten=false;
```
 hätte denselben Effekt. Es geht darum das man erst abfragt und dass der Zustand von weiterArbeiten auf Zeile 2 unbekannt ist wenn mehrere Threads auf weiterArbeiten zugreifen.


```
if (weiterArbeiten) {
   // hier kann ein Threadwechsel stattfinden
   weiterArbeiten != weiterArbeiten ;
}
```


----------



## Marco13 (18. Jan 2011)

FArt hat gesagt.:


> Wie so oft bei diesem einfachen Beispiel wurde vergessen den Zugriff auf das Flag zu synchronisiern.



...bzw. es volatile zu machen, was hier schon reichen würde.

EDIT @Andi_CH: Ich bin mir nicht sicher, ob irgendwo steht und formal zugesichert ist, dass die Variable sich überhaupt irgendwann (für den anderen Thread sichtbar) ändert. Man kann AFAIK einfach nicht davon ausgehen... :bahnhof:


----------



## FArt (18. Jan 2011)

Andi_CH hat gesagt.:


> Das stimmt zwar, aber was ist die schlimmste aller möglichen Folgen? Der Thread macht einen Loop zu viel und das ist wirklich nicht tragisch.



Nein, der Thread macht nicht einen Loop zu viel sonder bekommt die Änderung des Flags u.U. nie zu Gesicht. 
Wie gesagt: bis zum Erbrechen.. bitte Suche verwenden... bitte Spec lesen... Java Memory Model...


----------



## FArt (18. Jan 2011)

Marco13 hat gesagt.:


> ...bzw. es volatile zu machen, was hier schon reichen würde.



Das ist auch eine Synchronisierung ;-)


----------



## Andi_CH (18. Jan 2011)

Volatile? Wenn ich mich richtig erinnere hat das was mit Persistenz zu tun?
Übersehe ich etwas? Was für ein Fehler könnte denn theoretisch auftreten?


----------



## SlaterB (18. Jan 2011)

als Unterstützung: ich lese und schreibe hier im Forum offensichtlich auch ne Menge aber was hier der Fehler sein könnte ist mir bisher noch nicht an anderer Stelle als Erklärung vorgekommen, bitte genauer erklären,

wieso sollte der Thread nicht bei jedem while-Durchlauf den aktuellen Wert der Variablen prüfen?

'Spec' + 'Java Memory Model' ist bisschen hoch

edit:
http://www.java-forum.org/java-basics-anfaenger-themen/109684-problem-threads.html
Andi_CH müsste sich erinnern, schon damals von FArt darauf hingewiesen worden


----------



## L-ectron-X (18. Jan 2011)

Andi_CH hat gesagt.:


> Volatile? Wenn ich mich richtig erinnere hat das was mit Persistenz zu tun?


Nee, das war 
	
	
	
	





```
transient
```
.


----------



## Marco13 (18. Jan 2011)

Ich hatte davon auch keine Ahnung, aber bei JAX TV: Java-Programmierung im Multicore-Zeitalter sind mir damals einige :idea: aufgegangen. (Ich bin nur bedingt Fan von solchen Video-Präsentationen, aber das kann man sich wirklich mal ansehen). Die vereinfachte Quintessenz: Wenn ein Thread eine Variable ändert (wie in dem Fall, wo ein Thread die "arbeite " auf "false" setzt) ist NICHT zugesichert, dass der Thread, der diese Variable abfragt, diese Änderung sieht - AFAIR ist nichtmal zugesichert, dass er sie _überhaupt_ zu sehen bekommt, und schon gar nicht "kurz nachher" oder gar "sofort". NUR wenn die Variable als "volatile" dekariert ist, ist das sichergestellt (oder wenn die Variable in einem synchronized-Block verändert wurde - da kommen dann etwas kompliziertere Mechanismen zum Tragen, die in dem Video IMHO gut erklärt werden - man muss sie nicht auswendig wissen, sollte sich ihrer aber bewußt sein).  

@Andi_CH: Du meinst wohl "transient", was grob gesagt bedeutet, dass ein Field standardmäßig nicht mitserialisiert wird.


----------



## Andi_CH (18. Jan 2011)

FArt hat gesagt.:


> Nein, der Thread macht nicht einen Loop zu viel sonder bekommt die Änderung des Flags u.U. nie zu Gesicht.
> Wie gesagt: bis zum Erbrechen.. bitte Suche verwenden... bitte Spec lesen... Java Memory Model...



1. Warum sollte jemand die Suche bemühen bevor ein Problem auftaucht und auch dann fallen einem wohl kaum die richtigen Keywords ein, aber auch das Thema .... erbrechen und so ....

2. Wenn ich mich bei jeder Sprache in der ich programmiere erst um die Internas kümmern müsste, käme ich nie zum programmieren :-( Das Java Memory Model liest sich auch für in Englisch sehr geübte Leute nicht in einem Tag und ich würde sicher Wochen brauchen.

Für die Interessierten: Hier steht etwas zum Thema

Auf dem 2. Link bei google lese ich "...the volatile keyword in Java is poorly documented..." tönt ja SEHR vielversprechend :-(




Marco13 hat gesagt.:


> @Andi_CH: Du meinst wohl "transient", was grob gesagt bedeutet, dass ein Field standardmäßig nicht mitserialisiert wird.


Genau - hab ich verwechselt!

( Hab ich schon einmal gesagt, dass ich unbekehrbarer Ada-Fan bin? )


----------



## SlaterB (18. Jan 2011)

hab inzwischen bisschen was gelesen, ziemlich radikale Erkenntnis, dafür dass alle Welt im Grunde 'normale Threads' kennt,
und die auch quasi nie irgendwo in Testprogrammen Probleme machen, 
hab noch nie ein Anfänger-Thema mit 'mein Thread sieht Änderung xy nicht' gesehen..


----------



## Marco13 (18. Jan 2011)

Es funktioniert ja auch meistens ohne volatile. Aber es ist nicht zugesichert, dass es funktioniert


----------



## maki (18. Jan 2011)

Marco13 hat gesagt.:


> Es funktioniert ja auch meistens ohne volatile. Aber es ist nicht zugesichert, dass es funktioniert


Eben, manchmal gehts, erstaunlicherweise geht es bei SingleCore CPUs öfter als bei MultiCore CPUs, aber garantiert ist es nicht.

Da gibt es imho noch viele Bomben die Ticken weil Leute sich nicht wirklich mit dem JMM befasst haben und schlussfolgerten "geht doch", Mulithreading ist eben nicht intuitiv.

Tipp an alle denen das neu war: 
Angelika Langer schreibt sehr gute und imho verständliche Artikel zu diesem Thema: AngelikaLanger.com - Effective Java - A column by Angelika Langer & Klaus Kreft - Angelika Langer Training/Consulting (ab "since 2008")


----------



## SlaterB (18. Jan 2011)

das was in 5 Jahren bei 10.000 Leuten nie zu einem Fehler führte, 
könnte für ein Anfängerbeispiel wirklich genug sein 

da ist ja SwingUtilities.invokeLater() für jFrame.setVisible(true); wichtiger, da gibts wirklich manchmal Anzeigefehler


----------



## maki (18. Jan 2011)

SlaterB hat gesagt.:


> das was in 5 Jahren bei 10.000 Leuten nie zu einem Fehler führte,
> könnte für ein Anfängerbeispiel wirklich genug sein
> 
> da ist ja SwingUtilities.invokeLater() für jFrame.setVisible(true); wichtiger, da gibts wirklich manchmal Anzeigefehler


Die Frage lautet: Warum sollte man  einem Anfänger eine falsche Antwort geben?


----------



## FArt (18. Jan 2011)

maki hat gesagt.:


> Die Frage lautet: Warum sollte man  einem Anfänger eine falsche Antwort geben?



... die dann noch dazu über Google und die Forensuche für alle (die der Suche mächtig sind und gewillt sind diese einzusetzen) gefunden und nachgebaut wird.

Fehlerhaften Code in einem Javaforum unkommentiert zu lassen ist keine gute Idee. 

Und wie man hier sieht, gibt es sogar User die genau diese Diskussion schon ein oder zwei mal geführt bzw. geesehn haben und es immer noch nicht besser wissen, u.U. weil sie es öfter falsch als richtig gesehen haben ?!?  ... ;-)


----------



## Andi_CH (18. Jan 2011)

maki hat gesagt.:


> Da gibt es imho noch viele Bomben die Ticken weil Leute sich nicht wirklich mit dem JMM befasst haben und schlussfolgerten "geht doch", Mulithreading ist eben nicht intuitiv.
> 
> Tipp an alle denen das neu war:
> Angelika Langer schreibt sehr gute und imho verständliche Artikel zu diesem Thema: AngelikaLanger.com - Effective Java - A column by Angelika Langer & Klaus Kreft - Angelika Langer Training/Consulting (ab "since 2008")



Ich bleibe bei meiner Meinung - es ist ein Designfehler, dass das der Kompiler nicht selbst richtig macht!
Es kann nicht die Meinung sein, dass sich alle erst mit solchen und 1000 anderen Details auseinandersetzten müssen um stabile Sofware schreiben zu können. Mir wird schlecht wenn ich darüber nachdenke ob in einem Airbus, im Kontrollturm oder einem Kernkraftwerk irgendwo Java läuft und jede 1 Milliardste Änderung verloren geht... gibt es überhaupt irgend etwas das in Java mit 100% Sicherheit läuft? Eine Kompilerdirektive "all variables volatile" gibt es wohl nicht? Oder?

Leider schreibt die Angelika Langer auch in Fachchinesisch


----------



## maki (18. Jan 2011)

Andi_CH hat gesagt.:


> Ich bleibe bei meiner Meinung - es ist ein Designfehler, dass das der Kompiler nicht selbst richtig macht!
> Es kann nicht die Meinung sein, dass sich alle erst mit solchen und 1000 anderen Details auseinandersetzten müssen um stabile Sofware schreiben zu können. Mir wird schlecht wenn ich darüber nachdenke ob in einem Airbus, im Kontrollturm oder einem Kernkraftwerk irgendwo Java läuft und jede 1 Milliardste Änderung verloren geht... gibt es überhaupt irgend etwas das in Java mit 100% Sicherheit läuft? Eine Kompilerdirektive "all variables volatile" gibt es wohl nicht? Oder?
> 
> Leider schreibt die Angelika Langer auch in Fachchinesisch


Nun, wenn man Geld dafür verlangt in Java zu programmieren, sollte man schon so proffessionell sein und wissen was man tut.

Dass dieses verhalten "seltsam" erscheint mag stimmen, auch Angelika Langer nennt die fehlende "sequential consistency" (also das Prinzip das ein Thread Änderungen sieht die ein anderer Trhead _davor_ gemacht hatte) einen Desginfehler, sie erklärt aber wie man damit umgeht.

Wer sollte dass den sonst wissen müsen wenn nicht proff. Javaentwickler?


----------



## FArt (18. Jan 2011)

Andi_CH hat gesagt.:


> Ich bleibe bei meiner Meinung - es ist ein Designfehler, dass das der Kompiler nicht selbst richtig macht!
> Es kann nicht die Meinung sein, dass sich alle erst mit solchen und 1000 anderen Details auseinandersetzten müssen um stabile Sofware schreiben zu können. Mir wird schlecht wenn ich darüber nachdenke ob in einem Airbus, im Kontrollturm oder einem Kernkraftwerk irgendwo Java läuft und jede 1 Milliardste Änderung verloren geht... gibt es überhaupt irgend etwas das in Java mit 100% Sicherheit läuft? Eine Kompilerdirektive "all variables volatile" gibt es wohl nicht? Oder?
> 
> Leider schreibt die Angelika Langer auch in Fachchinesisch



Ich bin auch dafür, dass man Software intuitiv schreiben können muss. Ohne Doku zu lesen und wissen zu müssen was man tut usw. Das hält nur auf und belastet das Hirn unnötig. Das gilt auch für Fachbegriffe. Warum kann die das nicht einfach beschreiben? So mit Bienchen und Blümchen?

Leider sind nicht alle Leute so perfekt und auch in den Java Core haben sich Fehler und Unschönheiten eingeschlichen, die nicht einfach auszumerzen sind...

Du kannst alle Klassen vollständig synchronisieren. Preisfrage: warum ist das keine gute Idee, ob in Java oder in anderen Sprachen?


----------



## Marco13 (18. Jan 2011)

Um mal den Java-Fan raushängen zu lassen: Java macht es einem da schon ziemlich leicht. Man kann einfach Threads erstellen, wait und notify sind eingebaut und relativ leicht zu verstehen, das Fehlerpotential bei Multithreading ist immens, aber bei Java geradezu vernachlässigbar im Vergleich zu anderen Sprachen. Darüber hinaus: Wenn man in einer anderen Sprache eine generische, threadsichere BlockingQueue schreiben will, geht der Spaß erst richtig los  Bei Java gehören solche high-level-concurrency-Hilfsklassen zur Standard-API. Es gibt subtile Details, die einem die eine oder andere Durchdebuggte Nacht bescheren können, aber mal ganz lapidar: Es könnte schlimmer sein. Dass es auch highl-level-Sprachen gibt, bei denen es NOCH deutlich einfacher ist, will ich nicht bestreiten.


----------



## Andi_CH (18. Jan 2011)

Das Motto Java: Tippen, kompilieren, man meint es läuft.

Das Motto Ada: Tippen, kompilieren, läuft. (Den Aufwand betreibt man hier zu Beginn, bis man das mehr als sture Konzept verstanden hat - aber danach: "Freude herrscht" 

PThread für C++ habe ich auch mal eingesetzt - da hatte ich meine Liebe Mühe dass wirklich alle Threads mal Rechenzeit bekamen. Lieber nicht noch einmal. (Aber vielleicht lags am Symbian)

[JOKE]
Betreffend vollständige Synchronisation - warum soll das Nachteile haben ???:L
Warum denn überhaupt mehrere Threads? Mit nur einem ist man immer vollständig synchronisiert 
[/JOKE]


----------



## ThreadPool (18. Jan 2011)

maki hat gesagt.:


> Dass dieses verhalten "seltsam" erscheint mag stimmen, auch Angelika Langer nennt die fehlende "sequential consistency" (also das Prinzip das ein Thread Änderungen sieht die ein anderer Trhead _davor_ gemacht hatte) einen Desginfehler, sie erklärt aber wie man damit umgeht.



Das ist kein Designfehler, dass ist einfach mal modernen (mehrkernigen) Prozessorarchitekturen geschuldet, die kennen sowas nämlich auch nicht.


----------



## maki (18. Jan 2011)

ThreadPool hat gesagt.:


> Das ist kein Designfehler, dass ist einfach mal modernen (mehrkernigen) Prozessorarchitekturen geschuldet, die kennen sowas nämlich auch nicht.


Hab nachgesehen, Angelika Langer hat es doch keinen Designfehler genannt, war wohl wer anders, danke für die Korrektur


----------



## SlaterB (18. Jan 2011)

noch eine Nachfrage (könnte ich vielleicht irgendwo nachlesen, ich weiß  )
dass man nicht alles synchronisierten sollte ist klar, spricht aber etwas dagegen, alle Variablen in allen Klassen grundsätzlich als volatile anzusehen?


----------



## maki (18. Jan 2011)

> dass man nicht alles synchronisierten sollte ist klar, spricht aber etwas dagegen, alle Variablen in allen Klassen grundsätzlich als volatile anzusehen?


Volitale ist auch synchronisation.

Vereinfacht ausgedrückt (und bestimmt mit Fehlern ):
Volitale sorgt dafür, dass vor jedem lesenden Zugriff der Variable alle(!) Daten "frisch" aus dem Hauptspeicher in den "Cache" (Register) des Threads geladen werden, das nennt sich "refresh".
Jeder schreibende Zugriff sorgt dafür, dass die Daten vom Cache in den Hauptspeicher zurückgeschrieben werden, das nennt man "flush".
Das kostet Rechenzeit, ohne flush und refresh wird der Hauptspeicher soz. nicht mehr genutzt sondern nur noch der schnelle Thread Cache (Register), ausserdem muss u.U. die Pipeline der Prozessors neu aufgebaut werden, zu letzterem kenne ich keine Details.

synchronized verursacht übrigens auch einen Refresh vor dem synchronized Block/Methode und einen Flush danach, sperrt aber zusätzlich andere Threads aus über einen Lock.

synchronized/volatile nutzt man eben nur wenn nötig, da es kostet.


----------



## ThreadPool (18. Jan 2011)

SlaterB hat gesagt.:


> noch eine Nachfrage (könnte ich vielleicht irgendwo nachlesen, ich weiß  )
> dass man nicht alles synchronisierten sollte ist klar, spricht aber etwas dagegen, alle Variablen in allen Klassen grundsätzlich als volatile anzusehen?



Es spricht dagegen das "volatile" nur schwach ist. Du bekommst Probleme sobald eine Variable von einer anderen abhängt. Oder wenn du "atomare Operationen" ausführen möchtest hier ist z.B. ein Zähler wie ++y ein schönes Beispiel. Du bekommst unter Java diese "Anweisung" auch mit volatile nicht atomar da es tatsächlich 3 Anweisungen sind.


----------



## SlaterB (18. Jan 2011)

@maki
ach, um Performance soll man sich doch als allerletztes kümmern 
aber klingt schon sehr langsam, dann wohl auch keine Lösung

@ThreadPool
synchronized will ich ja nicht ersetzen, sondern nur das 'nicht lesen von Änderungen anderere Threads' verhindern, 
was hier als Problem für mich ziemlich neu ist,

gerade eine boolean-Änderung hier ist ja die einzige total atomare Operation, bei der sonst kein Fehler möglich ist,
die als einzige 'in einfacher Denkweise' ohne Synchronisation durchführbar ist


----------



## Andi_CH (18. Jan 2011)

Hm - liebe Moderatoren: Ist es technisch möglich die jetzt doch sehr tief gehend Diskussion vom eigentlichen Thread loszukoppeln und einen entsprechenden Titel zu setzen? Es hat ja mit dem ursprünglichen Thema nicht mehr viel zu tun.

(Ach ja, diese Posting könnte danach oder auch sonst gelöscht werden.)


----------



## FArt (18. Jan 2011)

SlaterB hat gesagt.:


> noch eine Nachfrage (könnte ich vielleicht irgendwo nachlesen, ich weiß  )
> dass man nicht alles synchronisierten sollte ist klar, spricht aber etwas dagegen, alle Variablen in allen Klassen grundsätzlich als volatile anzusehen?



Es geht hier um eine Synchronisations-Beziehung. Wenn keine solche Beziehung erkennbar ist, darf der Laufzeitcompiler Optimierungen vornehmen. Mit volatile werden alle Zugriffe auf diese Variable mit so einer Bedingung versehen, d.h. die eine Aktion passiert immer vor der anderen, z.B. Schreiben vor dem Lesen oder umgekehrt. Somit können bestimmte Optimierungen im Falle der unnötigen Verwendung von volatile nicht durchgeführt werden, was eine schlechtere Performance nach sich zieht.

In diesem Fall geht es darum, dass u.U. der Variableninhalt nicht aus dem Speicher gelesen wird sondern aus einem Register. Diese Optimierung (Speicherzugriff gespart) kann der Compiler vornehmen, weil zwischen Lesen und Schreiben keine Beziehung definiert wurde. Das kann aber bedeuten, dass der Inhalt des Registers sich vom Inhalt des Speichers unterscheidet. Hat (noch) keine Optimierung stattgefunden, wird man behaupten wollen, der Code wäre auch ohne volatile oder einen synchronized-Block funktionsfähig.

Muss man das genau so wissen? Nein.
Was muss man wissen? Wenn man mit mehreren Threads schreibend und/oder lesend auf Daten zugreift, muss eine Synchronisation durchgeführt werden. Das ist unabhängig von der Programmiersprache und muss immer berücksichtigt werden.

EDIT
Es geht um die Synchronisationsbeziehung, nicht die happens-before-Beziehung, da bin ich gerade durcheinander gekommen...


----------



## maki (18. Jan 2011)

> @maki
> ach, um Performance soll man sich doch als allerletztes kümmern
> aber klingt schon sehr langsam, dann wohl auch keine Lösung


Bei einem 4 Core Prozessor ist das schon relevant, sonst würde man in erster Linie kein Multithreading einsetzen und könne sich wait/notfy, synchronized, explizite Locks in mehreren Varianten und volitale sparen 

Wie gesagt, ist nicht intuitiv und anfangs u.U. sogar schokierend, sollte man aber dennoch wissen, oder besser: gerade deswegen



> gerade eine boolean-Änderung hier ist ja die einzige total atomare Operation, bei der sonst kein Fehler möglich ist,
> die als einzige 'in einfacher Denkweise' ohne Synchronisation durchführbar ist


Das Problem ist nicht nur der gleichzeitige Zugriff, sondern dass Threads Änderungen machen und diese mit sich "rumtragen" ohne anderen Threads bzw. dem RAM die Änderungen mitzuteilen.

@Andi_CH
Weiss nicht ob diese Diksussion "gut genug" ist um sie als eigenes Thema hinzustellen, hab nix dagegen, ein FAQ Beitrag oder Blog von jemandem der die Details besser kennt als ich wäre wohl auch nicht verkehrt, möchte aber keinem User hier "Arbeit zuteilen".


----------



## FArt (18. Jan 2011)

maki hat gesagt.:


> Bei einem 4 Core Prozessor ist das schon relevant, sonst würde man in erster Linie kein Multithreading einsetzen und könne sich wait/notfy, synchronized, explizite Locks in mehreren Varianten und volitale sparen



Nein, stimmt so nicht.
Auch einfache Systeme machen "Multithreading" und können auf Synchronisation nicht verzichten. Die einzelnen Threads werden aber in ihrer Abarbeitung nach dem Zeitscheibenprinzip unterbrochen und können somit auf die gleichen Probleme stoßen. Wenn eine Unterbrechung stattfindet, bevor ein konsistenter Datenstand hergestellt werden kann und der nächste "Thread" auf diese inkonsistenen Daten zugreift, hat der auch ein Problem (Stichwort: atomar). Das ganze mit nur einem "Kern" oder "Ausführungsthread"...


----------



## Sunchezz (21. Jan 2011)

interessante disskusion...

aber ich schätze die hilft mir nicht wirklich weiter, mal davon abgesehen das ich die sowieso volatile gemacht hätte... xD

Nein, das Problem was ich gerade sehe liegt daran das mein Thread keine Schleife hat und auch keine braucht.
Es gibt nur eine Sequenzielle aufgabe die einfach nur länger dauern kann, wegen einem Internetzugriff... 
Daher möchte ich die Möglichkeit geben diesen Vorgang abzubrechen.

Wenn ich jetzt nicht hinter jeder sequenziellen zeilenaufgabe noch ein if-konstrukt setzten möchte brauch ich also noch eine wirksame art einen Thread anders zu killen, von mir aus auch ohne rücksicht auf verluste! (wenn der Thread abgebrochen werden soll, wird eh nichts gespeichert oder geändert!)


----------



## SlaterB (21. Jan 2011)

das gibt es in Java nicht, keine Kraft der Welt kann einem Thread von außen reinreden,
siehe auch
http://www.java-forum.org/java-basics-anfaenger-themen/112197-methode-abbrechen.html

der kürzeste Test alle x Zeilen ist übrigens ein Aufruf a la check(); oder c();
darin kann dann eine Abbruch-Exception fliegen, wenn man partout ein if mit return und ähnliches vermeiden will


----------



## Sunchezz (21. Jan 2011)

also is die möglichkeit, den thread während der arbeit einfach null zu setzen auch unwirksam?
das kollidiert in meinem Kopf mit dem restlichen technischen Verständnis! ^^


----------



## SlaterB (21. Jan 2011)

inwiefern kollidiert das? auf Null-Setzen hat ja immer höchstens für den Auswirkung, der das macht, also z.B. das Objekt mit dieser Variablen (sofern man da von 'den' sprechen kann)

wenn ein Objekt seine Liste auf null setzt, dann ist diese ja auch nicht verschwunden, kann woanders noch gut weitergenutzt werden,


das Thread-Objekt steht auch nicht unbedingt für den Thread, interessante Verknüpfung an sich,
in der run()-Methode beginnt alles, aber ein Thread kann sich genausogut die restliche Zeit danach sonstwo im Arbeitsspeicher rumtreiben, das eigene Thread-Objekt braucht der gar nicht,
komplett verschwinden kann das Objekt allerdings auch nicht, über statische Methoden der Klasse Thread immer wiederzufinden


----------



## maki (21. Jan 2011)

> also is die möglichkeit, den thread während der arbeit einfach null zu setzen auch unwirksam?





> das kollidiert in meinem Kopf mit dem restlichen technischen Verständnis!


Muss wohl mit der innenseite der Schädeldecke kollidiert sein 

Seit wann hat das setzen einer Referenz auf null Auswirkungen auf das vorher referenzierte Objekt? 
Höchstens für den GC, aber der beendet auch keine laufenden threads.


----------



## tuttle64 (22. Jan 2011)

SlaterB hat gesagt.:


> das gibt es in Java nicht, keine Kraft der Welt kann einem Thread von außen reinreden,



was hälst du davon


```
public class EinThread extends Thread {

	int zahl = 0;

	public void run() {
		while (!Thread.currentThread().isInterrupted()) {
			try {
				Thread.currentThread();
				Thread.sleep(1000);
				System.out.println(++zahl);
			} catch (InterruptedException ex) {
				System.out.println("Achtung, Unterbruch!");
				Thread.currentThread().interrupt();
			}
		}
	}
}
```



```
import thread.*;

public class ThreadExample {
	public static void main(String[] args) {
		Thread thread = new EinThread();
		try {
			thread.start();
			Thread.currentThread().sleep(3000);
			// mit dem folgenden interrupt() wird der Thread angehalten
			thread.interrupt();
		} catch (InterruptedException ex) {
			ex.printStackTrace();
		}
	}
}
```

Was denkst Du, nach wievielen Sekunden dem Thread reingeredet wird? Richtig, nach 3 Sekunden.


----------



## Marco13 (22. Jan 2011)

Es ging wohl um sowas

```
public class EinThread extends Thread {

	int zahl = 0;

	public void run() {
		while (zahl < 100000000) {
    		    System.out.println(++zahl);
		}
	}
}
```

Was denkst du, wann _diesen_ Thread interessiert, dass auf ihm "interrupt" aufgerufen wurde? Richtig, nachdem er 100 Millionen Zeilen ausgegeben hat. Genau darum ging es (falls ich diesen Thread richtig in errinnerung habe) ja die ganze Zeit: Wenn man in einem solchen Thread nicht explizit _prüft_, ob er interrupted wurde (sei es mit isInterrupted() oder durch eine Operation, die eine InterruptedException werfen kann(!)), läuft er, bis er fertig ist.


----------



## tuttle64 (22. Jan 2011)

Marco13 hat gesagt.:


> Was denkst du, wann _diesen_ Thread interessiert, dass auf ihm "interrupt" aufgerufen wurde? Richtig, nachdem er 100 Millionen Zeilen ausgegeben hat. Genau darum ging es (falls ich diesen Thread richtig in errinnerung habe) ja die ganze Zeit: Wenn man in einem solchen Thread nicht explizit _prüft_, ob er interrupted wurde (sei es mit isInterrupted() oder durch eine Operation, die eine InterruptedException werfen kann(!)), läuft er, bis er fertig ist.



Und?


----------



## maki (23. Jan 2011)

tuttle64 hat gesagt.:


> Und?


Und: SlaterBs Aussage war richtig, dein Beispiel ist auch nur ein weiteres Beispiel dafür dass der Thread seine arbeit "freiwillig" einstellen muss.


----------



## OliverKroll (23. Jan 2011)

Mir stellt es sich so dar:

"volatile" heißt flüchtig und war am Anfang vermutlich für memory-mapped Input/Output; zum Beispiel, um einen AD-Wandler einzulesen.
Dem Compiler wird gesagt, daß eine volatile-Variable immer wieder neu aus dem Speicher geladen werden muß und nicht nur der in einer Registervariablen zwischengespeicherte Wert verwendet werden darf.

Dann hat man bei Sun gemerkt, daß in einem Mehrprozessorsystem theoretisch der Cache eines Cores nicht mit dem globalen Speicher übereinzustimmen braucht. Mit "volatile" übergeht man den Cache und liest direkt aus dem globalen Speicher.

Aber dieses Problem haben außer Sun auch andere erkannt, und so ist bereits von Intel auf einem Pentium die Cache-Kohärenz garantiert. Auf einem Intel Pentium braucht man sich über die Cache-Kohärenz keine Sorgen zu machen.

Weil Java in einer Mehrprozessor-Umgebung heutzutage nur auf einem Intel Pentium eingesetzt wird, deshalb darf man das "volatile" zur Thread-Beendigung gerne weglassen.
Windows, Linux und MAC OS X laufen heutzutage alle auf einem Intel Pentium.

Erklärung für "Cache-Kohärenz": Cache-Kohärenz ? Wikipedia

Intel unterstützt Cache-Kohärenz bereits seit 1993: Intel Pentium ? Wikipedia

Ein Apple-MacBook verwendet mindestens seit 2006 auch einen Intel Pentium: Apple MacBook ? Wikipedia

Edit: Allerdings stellt sich jetzt die Frage, was passiert, wenn die Variable "arbeite" in einer Registervariable gespeichert wird ...


----------



## P@u1 (23. Jan 2011)

OliverKroll hat gesagt.:


> Weil Java in einer Mehrprozessor-Umgebung heutzutage nur auf einem Intel Pentium eingesetzt wird, deshalb darf man das "volatile" zur Thread-Beendigung gerne weglassen.
> Windows, Linux und MAC OS X laufen heutzutage alle auf einem Intel Pentium.



War das ernst gemeint?
AMD hat auch nen guten Marktanteil (ich nehme zwar an, dass es dort auch Cache-Koherenz gibt, aber ist numal nicht das gleiche wie Intel).
Dazu kommt noch das mit den Registern, was du selbst schon gesagt hast.

Kann man dann wenn das mit der Cache-Koherenz so toll ist, davon ausgehen, dass bei Systemen, die Cache-Koherenz haben die memory-Flushes sich auf die Register beschränken, also sehr sehr wenig nur geflusht werden muss?


----------



## mjdv (23. Jan 2011)

Java hat doch schon das interrupted flag automatisch.
Thread (Java Platform SE 6)

edit: upsi, der thread hat ja mehrere seiten


----------



## Sunchezz (24. Jan 2011)

das mit der Kollision war nur eine Metapher um klar zu machen das ichs nicht verstehe ;-)

hmm, ok das Thread objekt treibt sich dann irgendwo rum, mit anderen worten das JMM "schafft" es nicht klar zu stellen das es eigentlich nicht mehr "existieren" sollte.
Kann ich dann das Thread Objekt nicht volatile setzen und damit allem klar machen was dieses Objekt benutzt oder abfragt das es null ist?


----------



## FArt (24. Jan 2011)

Wenn es nicht so lustig wäre, würde ich jetzt versuchen den Forenthread abzuwürgen. So hole ich mir lieber ein Bier und eine Tüte Chips und schaue weiter zu.
Bevor noch mehr wilde Halbwahrheiten auftauschen, sollte der eine oder andere Poster mal die JSR 133 lesen. Das Verhalten ist auf jeden Fall nicht bzw. nicht nur auf Mehrprozessorkerne bzw. -systeme zurückzuführen und es geht auch nicht darum, dass die VM oder das Design etwas "nicht schafft".... außer es zählt auch dazu, dass der Mensch es nicht schafft auf den Mond zu springen... in dem Sinne wäre das gerechtfertigt.

Ich schaue noch ein wenig zu... und "volatile" bringt immer viel Spaß ins Forum...  der nächste Forenthread mit Abbruch-Flag lässt nicht lange auf sich warten. Mal sehen was dann wieder abgeht... ;-)

Schöne Woche an alle...

[EDIT]
tuttle64 hat die beste Variante zu bieten, jedoch muss man auch hier richtig mit dem Interrupted-Flag umgehen, so wie es tuttle64 zeigt...


----------



## Landei (24. Jan 2011)

Ein Thread wird beendet:

- Wenn niemand mehr etwas schreibt
- Wenn der Mod ihn sperrt


----------

