Multithreads

El Hadji

Bekanntes Mitglied
Servus Community,
Folgendes mini Problem Wenn ich jetzt sagen wir von 1 bis 99 zählen wollen und ich dass mit 10 Thread erledigen will.
in der MainMethode erstelle ich einfach 10 Unterklassen von Threads:
Thread thread1 = new Zaehlthread(1, 9);
Thread thread2 = new Zaehlthread(10, 19);
.
.
Thread thread 10 = new Zaehlthread(90,99);

dann alle starten und joinen

In der Zaehlthread Methode geb ich einfach mit einer For-schleife die Werte aus. Wie kann ich die Synchronisieren dass wenn ich gerade Werte aus einem Thread zurückgebe kein andere Thread auch welche zurückgibt. (Nur in der Zaehlthread-Klasse). Ich habe die Methode schon synchronized bringt aber genau nichts.
mfg El Hadji
 

httpdigest

Top Contributor
Kommt drauf an, was du denn als Ergebnis erreichen möchtest. Sollen alle 10er Blöcke untereinander parallel aber innerhalb jedes 10er Blocks sequenziell abgearbeitet werden?
Also wäre das hier eine valide Ausgabe?
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 80, 81, 82, 83...
aber das nicht:
0, 20, 1, 21, 2, 22, 23, 24, 3, 25, 26, 4, 5, 6,...
Oder sollen alle 10er Blöcke sowohl untereinander als auch innerhalb jedes 10er Blocks parallel laufen?
Beschreibe doch erstmal, was du ganz genau als Ergebnis haben möchtest.
 

Tarrew

Top Contributor
Zeig mal deine Zaehlthread-Klasse.

Wie soll das denn ablaufen?
Der 2. Thread wartet bis der erste die Zahlen 1-9 ausgegeben hat und gibt dann 10-19 aus und dann startet der dritte Thread etc? Oder haste dir das anders gedacht?

#Edit: Immer Sekunden zu spät :p
 

El Hadji

Bekanntes Mitglied
Code:
public class ZaehlThread extends Thread
{
    private int  start;
    private int  ende;
   
    public ZaehlThread(int start, int ende)
    {
     this.start = start;
     this.ende = ende;
    }

 
    public void print()
    {
        for(int i = start; i <= ende; i++)
        {
            System.out.println(i);
        }
    }
   
    public void run()
    {
        print();
    }
}
 

El Hadji

Bekanntes Mitglied
Kommt drauf an, was du denn als Ergebnis erreichen möchtest. Sollen alle 10er Blöcke untereinander parallel aber innerhalb jedes 10er Blocks sequenziell abgearbeitet werden?
Also wäre das hier eine valide Ausgabe?
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 80, 81, 82, 83...
aber das nicht:
0, 20, 1, 21, 2, 22, 23, 24, 3, 25, 26, 4, 5, 6,...
Oder sollen alle 10er Blöcke sowohl untereinander als auch innerhalb jedes 10er Blocks parallel laufen?
Beschreibe doch erstmal, was du ganz genau als Ergebnis haben möchtest.
Genau die Blöcke sollten untereinander parallel aber innerhalb des 10er Blocks sequenziell abgearbeitet werden.
 

httpdigest

Top Contributor
Dann z.B. so:
Java:
public void print() {
  synchronized (ZaehlThread.class) {
    for(int i = start; i <= ende; i++) {
      System.out.println(i);
    }
  }
}
Lese dir bezüglich des synchronized Schlüsselwortes nochmal die Doku durch:
https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

Du hast wahrscheinlich einfach das synchronized Schlüsselwort an die run() oder print() Methode geschrieben. Das funktioniert natürlich nicht, da du ja 10 Thread Instanzen hast, also 10 Lock-Objekte (synchronized an Instanzmethoden synchronisiert immer nur auf das Objekt, auf dem die Methode aufgerufen wird!).

Einfacher wäre es aber vielleicht so:
Java:
java.util.stream.IntStream.
range(0, 10).
parallel().
forEach(i -> java.util.stream.IntStream.
             range(i * 10, (i + 1) * 10).
             forEach(System.out::println));
 

httpdigest

Top Contributor
ich hab es auch mit einem synchronized(this) -Block probiert
Ja, das geht natürlich auch nicht. synchronized (this) ist äquivalent zu einem synchronized an der Instanzmethode. `this` in diesem Fall wäre dann ja jedes der 10 Thread Objekte. Du musst halt ein einziges Objekt haben, was als Lock dient. Z.B. eine static Klassenvariable oder halt (wie in meinem Fall) der Einfachheit halber das Klassenobjekt.
 

httpdigest

Top Contributor
ok und als statisches Attribut könnte ich dann den Startwert oder den Endwert nehmen oder müssen es beide sein?
Häh?!
Nein, du brauchst nur ein einziges Lock-Objekt (und es muss auch ein Objekt! sein), auf das du per `synchronized(dasLockObjekt)` synchronisierst. Alles andere kannst du so lassen wie es ist. Schau dir einfach meinen vorgeschlagenen Code an.

Alternativ auch so:
Java:
public class ZaehlThread extends Thread {
  private static final Object lock = new Object();
  private int start;
  private int ende;
  public ZaehlThread(int start, int ende) {
    this.start = start;
    this.ende = ende;
  }
  public void print() {
    synchronized (lock) {
      for (int i = start; i <= ende; i++) {
        System.out.println(i);
      }
    }
  }
  public void run() {
    print();
  }
}
 

El Hadji

Bekanntes Mitglied
ahh ok sorry, ich bin auf dem schlauch gestanden.
Und wenn ich noch zusätzlich die Reihenfolge anpassen will also das die 10 Thread auch innerhalb parallel laufen also 0,1,...,99 ausgeben. Funktioniert das noch parallel oder müsste ich direkt nach jedem thread.start() gleich joinen was ja die Parallelläufigkeit unterbinden würde.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
N Matrizenberechnung mit Multithreads Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben