threadsfrage

milexy86

Mitglied
Hallo Leute,

ich gehe gerade in die Thematik der Threads ein. Wozu sie das sind weiss ich. Ich versuche dieses Beispiel aus "Java ist auch eine Insel" auszuführen. Zwanzig mal soll die ausgabe des aktuellen Datums erolgen und 2 mal der zähler. Diese operationen sind durch je 2 Threads auszuführen.:

Java:
 public class DateCommand implements Runnable {          // Dient zur Ausgabe des Aktuellen Datums
	
	@Override public void run(){
		for (int i = 0; i<20; i++){
			 System.out.println( new java.util.Date() );
		}
	}
}


public class CounterCommand implements Runnable {      //Ausgabe des Zählers
	@Override public void run(){
		for (int i=0;i<20;i++){
			System.out.println(i);
		}
	}



public static void main (String args[]){                         // Starten der Threads
	Thread t1 = new Thread (new DateCommand());
	t1.start();
	
	Thread t2 = new Thread (new CounterCommand());
	t2.start();
      }
}


Ausgabe ist folgende:

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012
Fri Sep 28 16:43:56 CEST 2012


Sollte die Ausgabe aber nicht abwechselnd ausgeführt werden,was auch der Sinn von Threads ist, also in der Art:

Fri Sep 28 16:43:56 CEST 2012
0
1
2
3
4
5
6
7
8
9
10
Fri Sep 28 16:43:56 CEST 2012
11
12
13
14
15
16
17
18
19
Fri Sep 28 16:43:56 CEST 2012
.
.
.
.
.
.

Freue mich auf Antworten :)
 

Network

Top Contributor
Hast du es mal mit längeren Schleifendurchläufen probiert?
Also 2000 statt 20.

Threads haben den Sinn, dass sie "parallel" laufen. Das wird aber nicht von jedem Betriebssystem unterstützt und auch oft jedesmal anderst gehandhabt.
So muss man z.B. bei manchen noch die Priorität angeben, da sonst erst der eine durchläuft dann der andere.
Die neueren Windows haben einen relativ intelligenten Threadcontroller, bei Linux gibts so allerlei.
 

Marco13

Top Contributor
Wenn man statt der 20 mal eine 20000 verwendet wird die Console vollgespammt und man sieht die ersten Daten zwischen den Zahlen. Alternativ mal in beide for-Schleifen jeweils
Java:
                try
                {
                    Thread.sleep((int)(Math.random()*100));
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
                }
einfügen.
 

Bernd Hohmann

Top Contributor
Du bist auf ein gerne ignoriertes Problem gestossen: Die Erzeugung eines Threads ist "teuer" (dh. braucht relativ viel Zeit).

t1.start() wird aufgerufen und kehrt erst zurück, wenn run(..) erreicht wurde. Wärend die Ausgabe des ersten Threads läuft, wird t2.start() ausgeführt - das dauert auch wieder eine Weile bis der sich zu "run()" vorgearbeitet hat - daher kommt das hintereinander statt gleicheinander.

Füge mal in beiden Routinen hinter dem System.out eine kleine Warteschleife ein um das künstlich zu bremsen:
Java:
try {
   Thread.sleep(100);
} catch (InterruptedException e) {}

Bernd
 

Marco13

Top Contributor
@Bernd: Ziemlich genau das hatte ich auch geschrieben - bis ich dann mit einem leichten :autsch: WTF? :autsch: gemerkt habe, dass die Ausgabe des zweiten (!) Threads zuerst erscheint - erklären kann ich mir das so spontan auch nicht, aber ein "Threads werden vom Betriebssystem verwaltet, und man weiß nie 100% genau, wann ein Thread wirklich losläuft" reicht mir persönlich da erstmal.
 

milexy86

Mitglied
Hey, sehr interessant das mit euren Ansätzen!.

Habe mal den zähler auf 200 000 gestellt und mann konnte ab un zu mal die Daten zwischen den Zahlen sehen. Auch das mit der Exception in der for Schleife hat funktioniert und er gibt die Daten zwischen den Zahlen aus so wie es ihm passt (mal nach der 2 zeile, dann nach der 4, dann einpaar hintereinander...). Sehr interessant!.

Eine frage nebenbei:

Wenn man das Programm auf einen 2-Kern prozessor ausführt, dann wird Thread 1 auf Kern 1 ausgeführt und Thread2 auf Kern 2?. Das heisst beide Kerne sind dann zu 100% ausgelastet.

Ich habe das auf einen 4-Kern Prozessor ausgeführt und alle 4 wahren dann zu 100% ausgelastet. Werden dann intern irgendwie aus diesen 2 Threads ... 4Threads erzeugt?.
 

Network

Top Contributor
Also die Java Runtime arbeitet bereits im Hintergrund automatisch mit eigenen mehreren Threads.

Wie Marco und Ich bereits schrieben, liegt die Verwaltung und Handhabung mit Threads im Ermessen des jeweiligen Betriebssystemes.
Eine genaue Aussage kann man dazu nicht machen. Zwei Threads können bei einem Mehrkernprozessor auch auf den selben Kern gelegt werden. Ein Thread nimmt standardmäßig nicht 100% der CPU-Leistung ein, soetwas kann aber natürlich vorkommen.
Wenn das Betriebssystem jetzt intelligent entwickelt wurde so werden die Threads auf die Kerne verteilt, sodass ein Kern nicht mit 2 Threads handhaben muss die jeweils 100%+ der Kernleistung in Anspruch nehmen.

Gruß
Net
 

kaetzacoatl

Bekanntes Mitglied
Der zweite Thread ist einfach viel schneller.
Der erste muss Objecte erzeugen und diese
dann ausgen. Der zweite nur Zahlen.
Mess mal die Zeit, die die Threads jeweils
benötigen.
 

Bernd Hohmann

Top Contributor
@Bernd: Ziemlich genau das hatte ich auch geschrieben - bis ich dann mit einem leichten :autsch: WTF? :autsch: gemerkt habe, dass die Ausgabe des zweiten (!) Threads zuerst erscheint - erklären kann ich mir das so spontan auch nicht, aber ein "Threads werden vom Betriebssystem verwaltet, und man weiß nie 100% genau, wann ein Thread wirklich losläuft" reicht mir persönlich da erstmal.

Jo, ich hab gesehen dass wir den gleichen Murx geschrieben haben. Trotzdem: Nicht nur vor Gericht und auf Hoher See - auch bei Threads ist man in Gottes Hand.

Soweit ich mich erinnern kann, wird erst mit start() entschieden, wo und wie der Thread laufen wird. Mit etwas Pech hat das Anstoßen des ersten Threads bzw. die ersten Zeilen im run() so lange gedauert, dass der Scheduler des OS den Thread erstmal wieder zurückstellt.

Kurzlaufende Threads sind also eher zu vermeiden, insbesondere wenn man damit damit Nebenläufigkeit demonstrieren möchte :)

Ich schreib mal Christian Ullenboom an dass er das Beispiel überarbeitet (mit Verweis auf diesen Thread).

Bernd
 

Bernd Hohmann

Top Contributor
Christian hat geantwortet, dass er bei der nächsten Überarbeitung einen entsprechenden Hinweis auf die nicht-deterministik von Threads anbringen wird (was auch immer das einem Anfänger bringen wird - ich habs nach kurzer Diskussion drangegeben).

Bernd
 

milexy86

Mitglied
@Marco:

Sorry,habe mich falsch Ausgedrückt, aber verstanden.

Bei dieser Variante:

Java:
try {
   Thread.sleep(100);
} catch (InterruptedException e) {}

gibt er tatsächlich die Ausgaben abwechselnd aus, im gleichen Schritt.

Eine weitere Frage (vlt. bischen dumme):
Kann man die Threads explizit den jeweiligen Prozessorkernen zuweisen, also manuell ohne dem Eingriff des Betriebssystem?
 

Ark

Top Contributor
Die neueren Windows haben einen relativ intelligenten Threadcontroller
"Relativ" ist wohl relativ. Nach meinen Erfahrungen ruckelte bei jeder Sinnlos-Version (ja, auch unter Sinnlos 7) irgendwann mal ständig der Mauscursor, selbst bei CPU-Leerlauf.
bei Linux gibts so allerlei.
Was meinst du damit? Vielleicht habe ich noch nicht genug gesehen (wer probiert schon alle Scheduler durch?! xD), aber zumindest auf meinem Linux konnte ich schon öfters selbst unter CPU-Volllast (beide Kerne!) im Web surfen, als wär' nix.

@milexy86: Mit Java wird das wahrscheinlich schwierig, vermute ich mal. Aber selbst dann: Wenn dein Programm nur dann richtig läuft, wenn das Scheduling vollkommen vorhersehbar arbeitet, ist das eher ein Hinweis auf schlechtes (ganz schlechtes!) Design. Ein Programm sollte immer korrekt arbeiten, selbst bei abstrusestem Scheduling.

Ark
 

Bernd Hohmann

Top Contributor
Kann man die Threads explizit den jeweiligen Prozessorkernen zuweisen, also manuell ohne dem Eingriff des Betriebssystem?

taskset/procbind unter Linux existiert, nehme ich ab und an um Prozessorhopping zu vermeiden. Wirklich Sinn macht das aber unter Java nicht wirklich - wenn Echtzeitverhalten gefordert wird, sollte man auch entsprechende Betriebssysteme nehmen und konventionelles Java wegen der asynchronen GC eher meiden.

Uralt-Java war da schick, weil man die GC in dem Moment manuell anstossen konnte wo es am wenigsten weh tat.

Bernd
 

Network

Top Contributor
[OT]
"Relativ" ist wohl relativ. Nach meinen Erfahrungen ruckelte bei jeder Sinnlos-Version (ja, auch unter Sinnlos 7) irgendwann mal ständig der Mauscursor, selbst bei CPU-Leerlauf.

Was meinst du damit? Vielleicht habe ich noch nicht genug gesehen (wer probiert schon alle Scheduler durch?! xD), aber zumindest auf meinem Linux konnte ich schon öfters selbst unter CPU-Volllast (beide Kerne!) im Web surfen, als wär' nix.

@milexy86: Mit Java wird das wahrscheinlich schwierig, vermute ich mal. Aber selbst dann: Wenn dein Programm nur dann richtig läuft, wenn das Scheduling vollkommen vorhersehbar arbeitet, ist das eher ein Hinweis auf schlechtes (ganz schlechtes!) Design. Ein Programm sollte immer korrekt arbeiten, selbst bei abstrusestem Scheduling.

Ark

Also deine CPU Probleme mit Windows kann ich leider nicht nachvollziehen. Ehrlich gesagt habe ich auch noch nie die Maus ruckeln sehen in irgendeiner Weise ???:L. Nach dem letzten was ich gehört habe, soll Microsoft in diesem Bereich am fortschrittlichsten sein, wenn sich die Leistungsfähigkeiten auch noch immer nicht annähernd im gewünschten Bereich befinden.
Das war zwar irgendein Artikel vor ein paar Jahren, da ich aber noch nie die gegenteilige Situation entdeckt habe, nein sogar im Gegenteil, ging/gehe ich von der Richtigkeit dieses Artikels aus.

Meine letzte persöhnliche Erfahrung mit Linux war, dass das System die Threads schön ala Priorität 10 nacheinander abgearbeitet hatte, die Information ist jetzt gut aber auch 5 Jahre alt wieder. Aber da scheint es die unterschiedlichsten Erfahrungen zu geben. Unter Linux ist es sowieso schwer eine einheitliche Aussage zu geben.[/OT]
 

kaetzacoatl

Bekanntes Mitglied
Warum willst du mehrere Kerne benutzen?
Die Dinger sind heute so schnell, dass es
wirklich erst bei sehr sehr vielen Threads
merkliche unterschiede gibt.
 

Marco13

Top Contributor
Der einzige Grund, gezielt Threads Kernen zuweisen zu wollen, der mir spontan einfallen würde, wäre ein Benchmark. "Wie schnell würde die Applikation mit n Threads auf einem m-Kerner laufen?". In der Praxis braucht man so eine explizite Zuweisung wohl selten, aber in dieser Form kann das eine berechtigte Frage sein.
 

Ark

Top Contributor
[OT]
Nach dem letzten was ich gehört habe, soll Microsoft in diesem Bereich am fortschrittlichsten sein, wenn sich die Leistungsfähigkeiten auch noch immer nicht annähernd im gewünschten Bereich befinden.
Das war zwar irgendein Artikel vor ein paar Jahren, da ich aber noch nie die gegenteilige Situation entdeckt habe, nein sogar im Gegenteil, ging/gehe ich von der Richtigkeit dieses Artikels aus.
Nun, wenn das Scheduling unter Linux so schlecht wäre, würden wohl kaum fast alle der Top 500 auf Linux setzen, schätze ich mal. (Gut, das mit Linux kann da natürlich auch andere Gründe haben.) Und zum Echtzeitverhalten wurde erst vor einem halben Jahr (wieder?) gezeigt, dass Linux kaum Wünsche offen lässt.

Meine Erfahrungen vor allem mit neuen Entwicklungen unter Windows 7 sind aber eher begrenzt, insofern würde mich der Artikel da gerade mal interessieren, den du erwähnt hast.[/OT]
Ark
 

Neue Themen


Oben