Threads

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

Threads
habe mir den code angeschaut aber irgendwie werde ich nicht schlau draus?
bzw könnte jemand den code erklären ?
greifen die einzelnen Threads auf die schwesterklasse zu ?
was bewirkt die Schleife?

final int threads = Integer.parseInt(args[0]);
    final Thread[] ts = new Thread[threads];     
    for (int i = 0; i < threads; i++) {
      ts[i] = new MyThread(i);       
    }
    for (Thread t : ts) {
      t.start();
    }
    for (Thread t : ts) {
      t.join();
    }

Die einzelnen Threads werden initialisiert mit folgender Zeile:

ts[i] = new MyThread(i);    

Das heißt deren dynamische Klasse ist MyThread; es handelt sich also um Objekte dieser Klasse. Wenn ich jetzt auf diesem Thread die start-Methode aufrufe, dann wird dort die run-Methode ausgeführt.


Habe mal gelesen ein Teil des Codes wird sequentiell bei start() ausgeführt ein anderer Parallel run()

Bei Runnable geht es genauso ?

 public static void main(String[] args) throws InterruptedException {
    final int threads = Integer.parseInt(args[0]);
    final Thread[] ts = new Thread[threads];
    for (int i = 0; i < threads; i++) {
      ts[i] = new Thread(new MyRunnable(i)); <- wieso?
    }
    for (Thread t : ts) {
      t.start();
    }
    for (Thread t : ts) {
      t.join();
    }
  }

man kann ja die Anzahl Threads mit Arbeitspaketen bestimmen

 final int threads = Integer.parseInt(args[0]);   
    ExecutorService e = Executors.newFixedThreadPool(threads);
    for (int i = 0; i < threads; i++) {
      e.execute(new MyRunnable(i));   <- wieso muss man es so implementieren ?

Angenommen, die [m]run[/m]-Methode deines [m]MyThread[/m]s sähe so aus:

public void run() {
  foo();
}

Und deine [m]main[/m]-Methode sähe so aus:

Thread t = new MyThread(...);
t.start();
bar();

Dann werden [m]foo[/m] und [m]bar[/m] parallel ausgeführt:

(t.start()) -----
     |           |
     |           |
( bar() )    ( foo() )

Bei [m]join[/m] würden diese „Ausführungsstränge“ wieder zusammenfließen.

Bei mehreren Threads in einer Schleife würden in obiger „Grafik“ weitere [m]foo[/m]-Blöcke rechts hinzukommen.

Hier wird ein neuer Thread erzeugt, der die [m]run[/m]-Methode der übergebenen [m]Runnable[/m]-Instanz aufruft. Eine [m]Runnable[/m]-Instanz alleine enthält i.A. keine Logik zur parallelen Ausführung ([m]Runnable[/m] ist schließlich ein Interface). Der dynamische Typ ist also [m]Thread[/m], der aber mit einem speziellen Konstruktor erzeugt wurde.

Hier wird ein [m]ExecutorService[/m] bzw. Thread-Pool erzeugt, der die gegebene Anzahl an Threads verwendet. Die [m]execute[/m]-Methode teilt dem [m]ExecutorService[/m] nun mit: Führe die [m]run[/m]-Methode der übergebenen [m]Runnable[/m]-Instanz auf irgendeinem der Arbeiter-Threads aus. Das ist eben einfach die Schnittstelle des [m]ExecutorService[/m]-Interfaces.

2 Likes

Wettlaufsituation
Ich verstehe die eine Übungsgolie nicht bezüglich wettlaufsituation Übung 3
Wieso kann der Wert count kleiner sein bei > 3 Threads


Hi,

Das liegt daran, dass die +±Operation in drei Teile aufgeteilt ist, nämlich:
Das Lesen des Variablen-Werts.
Das lokale Rechnen (aka Ändern) des Variablen-Werts + 1.
Das Schreiben des Ergenisses zurück in die Variable.

Daher auch der Name der Lesen-Ändern-Schreiben-Wettlaufsituation.

Wenn nun alle Threads gleichzeitig den Wert lesen, erhält jeder Thread zum lokalen Rechnen den Wert 0 (default-Wert für int-Datentyp).
Somit erhält jeder Thread als Ergebnis 1, und jeder Thread schreibt nun auch eine 1 zurück in die Variable.

Da das Lesen, Ändern und Schreiben der verschiedenen Threads beliebig verschachtelt sein kann (T1 liest und ändert, T2 liest, T3 liest ändert schreibt, T2 ändert, T4 liest usw.) kann eben die Variable counter entweder gar nicht den Wert 3 annehmen, genau einmal, oder beliebig oft (Beliebig oft, wenn die Variable counter richtig auf 2 erhöht wurde und dann mehrere Threads diese 2 aus der Variable herauslesen und damit arbeiten).


alles Klar ! und bei Prüfe-Handle wie ist es da ?
Nr.3.2

andere Frage

[code]
public class ClassSync {
static int a = 0;
private static synchronized int getNextNumber() { ← hier?
return a++;
}
public static void main(String[] args) {
System.out.println(“Start.”);
for (int i = 0; i < 5; i++) {
new Thread() {
@Override
public void run() {
System.out.println(“This is Thread”

  • getNextNumber());
    }
    }.start();
    }
    System.out.println(“End.”);

[/code] an was synchronisiert die Methode? heißt das nur ein Thread diese Methode betreten kann, die anderen müssen Warten ?