nochmal synchronisierte Methoden

El Hadji

Bekanntes Mitglied
Servus Community,
Ich hab hier ein kleines Problem und komm nicht mehr weiter. Was sagt ihr zu meinem Code bis jetzt. Folgende Angabe:
e0o984ik06rjo0uau.jpg

Hier mein Code bis jetzt:
Code:
package threads;

import threads.geg.Receiver;
import java.util.*;

public class Communicator implements Receiver
{
   
    private HashMap <String, Receiver> liste;
    private static  Object lock = new Object();
    private static Object lock2 = new Object();
    private int zaehler;
    private String name;
    private int send;
    private int sendAll;
  
    public Communicator()
    {
       liste = new HashMap<String,Receiver>();
       zaehler = 0;
       name = "Receiver";
       send = 0;
       sendAll =0;
    }

 
    public void receive(String message)
    {
      System.out.println(message);
    }
   
    public synchronized String signUp(Receiver aReceiver)
    {
        if(liste.containsValue(aReceiver))
        {
            return name;
        }
       
        zaehler++;
        name = "Receiver" + zaehler;
        liste.put(name, aReceiver);
        return name;
      
    }
   
    public void send(String identifier, String message)
    {
       synchronized (lock)
       {
           while(sendAll > 0)
           {
               try
               {
               wait();
               send--;
            }
           
            catch(InterruptedException e)
            {
                throw new RuntimeException(e);
            }
            }
           
            if(!liste.containsKey(identifier))
            {
                throw new RuntimeException("Invalid identifier");
            }
           
            liste.get(identifier).receive(message);
            send++;
            this.notifyAll();
        }
      
    }

   
   
    public synchronized void sendAll(String message)
    {
      
       
        while(send > 0)
        {
            try
            {
                wait();
                sendAll--;
            }
            catch(InterruptedException e)
            {
                throw new RuntimeException(e);
            }
        }
       
        Set<String> neu = liste.keySet();
       
        for(String f : neu)
        {
            liste.get(f).receive(message);
        }
        sendAll++;
        this.notifyAll();
    }
   
   
}

Ich würde mich über eine Antwort freuen
mfg El Hadji
 

httpdigest

Top Contributor
Nein. Das ist leider komplett falsch. Schau dir doch nurmal die signUp() Methode an. Hier würdest du ja immer den Namen des zuletzt hinzugefügten Receivers zurückgeben, wenn versucht wird, irgendeinen Receiver, der bereits registriert ist, erneut zu registrieren. Du solltest dir schon ein Mapping von Receiver auf String merken.
Dann ist das Locking einmal zu restriktiv und zweitens völlig falsch. Aktuell darf nur ein einziger Thread überhaupt an irgendeinen Receiver per send(String identifier, String message) senden, da - egal welcher Receiver - immer über dasselbe lock Objekt synchronisiert wird.
Dann ist die Prüfung von sendAll innerhalb von send() nicht korrekt mit dem Aktualisieren dieses Zählers in sendAll() synchronisiert. Der Zähler kann völlig verschränkt zueinander aktualisiert und gelesen werden. Wenn auf gemeinsame Variablen zugegriffen wird, muss IMMER über dasselbe Lock-Objekt synchronisiert werden. sendAll() synchronisiert hier über this während send() über das lock Objekt synchronisiert.
Außerdem muss du darauf achten, dass alle Zugriffe auf die "liste" korrekt synchronisiert sind, wenn mehrere Threads gleichzeitig send(), sendAll() und/oder signUp() aufrufen.
Das, was du machen sollst, ist alles andere als einfach, lässt sich aber vorzüglich mittels der ReadWriteLock/ReentrantReadWriteLock Klasse vom JRE realisieren - falls du das nutzen darfst.
 

El Hadji

Bekanntes Mitglied
Ok ich wollte natürlich auch die Receiver als Key nehmen, aber die Methode send will ja den String als identifier haben. Sprich ich übergebe den Value-Wert und da könnte ich ja eine Nachricht an 2 Receivern gleichzeitig schicken falls die eben den gleichen Value haben.

Ah ok ich dachte mit dem lock, verhindere ich dass die send Methode an 2 gleiche Receiver gleichzeitig sendet. Also besser ein synchronized(this).

Ja mit dem Zähler des SendAll() war mir klar, wusste aber nicht wie ich das verhindern kann.

Leider eben nicht, wir dürfen nur eine selbstgeschrieben CheckAndSet-Methode verwenden
 

httpdigest

Top Contributor
Ok ich wollte natürlich auch die Receiver als Key nehmen, aber die Methode send will ja den String als identifier haben. Sprich ich übergebe den Value-Wert und da könnte ich ja eine Nachricht an 2 Receivern gleichzeitig schicken falls die eben den gleichen Value haben.
Du musst natürlich sicherstellen, dass nicht zwei Receiver denselben Identifier/Schlüssel bekommen. Das ist ja klar, denn dann weißt du ja in send() nicht, welchem Receiver du nun die Nachricht schicken sollst.
Ah ok ich dachte mit dem lock, verhindere ich dass die send Methode an 2 gleiche Receiver gleichzeitig sendet. Also besser ein synchronized(this).
Nein, die Synchronisation auf dasselbe Lockobjekt (ob das nun `lock` ist oder `this` ist völlig wurscht) verhindert doch, dass du überhaupt an zwei oder mehr Receiver eine Nachricht gleichzeitig senden kannst.
 

httpdigest

Top Contributor
Hier ist eine (wahrscheinlich) funktionierende Lösung (habe die Funktionalität in viele kleine, leicht zu verstehende Methoden aufgeteilt):
Java:
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
interface Receiver {
  void receive(String message);
}
public class Communicator {
  private final Map<Receiver, String> r2i = new HashMap<>();
  private final Map<String, Receiver> i2r = new HashMap<>();
  private int sequence;
  private int shared;
  private boolean exclusive;
  private <T> T doExclusively(Supplier<T> r)
      throws InterruptedException {
    lockExclusive();
    try {
      return r.get();
    } finally {
      unlockExclusive();
    }
  }
  private void lockExclusive() throws InterruptedException {
    synchronized (this) {
      while (shared > 0 || exclusive)
        wait();
      exclusive = true;
    }
  }
  private void unlockExclusive() {
    synchronized (this) {
      exclusive = false;
      notifyAll();
    }
  }
  private void doShared(Runnable r) throws InterruptedException {
    lockShared();
    try {
      r.run();
    } finally {
      unlockShared();
    }
  }
  private void lockShared() throws InterruptedException {
    synchronized (this) {
      while (exclusive)
        wait();
      shared++;
    }
  }
  private void unlockShared() {
    synchronized (this) {
      shared--;
      notifyAll();
    }
  }
  public String signUp(Receiver receiver) throws InterruptedException {
    return doExclusively(() -> r2i.computeIfAbsent(receiver, (r) -> {
      String someIdentifier = Integer.toString(sequence++);
      i2r.put(someIdentifier, receiver);
      return someIdentifier;
    }));
  }
  public void send(String identifier, String message)
      throws InterruptedException {
    Receiver receiver = doExclusively(() -> {
      if (!i2r.containsKey(identifier))
        throw new RuntimeException("Invalid identifier!");
      return i2r.get(identifier);
    });
    doShared(() -> {
      synchronized (receiver) {
        receiver.receive(message);
      }
    });
  }
  public void sendAll(String message) throws InterruptedException {
    doExclusively(() -> {
      r2i.keySet().forEach(r -> r.receive(message));
      return null;
    });
  }
  public static void main(String[] args) throws InterruptedException {
    Communicator c = new Communicator();
    String id1 = c.signUp((msg) -> System.out.println("1:" + msg));
    String id2 = c.signUp((msg) -> System.out.println("2:" + msg));
    IntStream.range(0, 1000).parallel().forEach(i -> {
      try {
        if ((i % 2) == 0)
          c.sendAll("to all");
        else if ((i % 3) == 0)
          c.send(id1, "to one");
        else
          c.send(id2, "to two");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    });
  }
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Ostkreuz Wieso wird die Methode nochmal aufgerufen? Java Basics - Anfänger-Themen 5
J Hinzufügen eines Objekts in eine Liste, um später dann nochmal auf das Objekt zugreifen zu können Java Basics - Anfänger-Themen 8
B Unique ID nochmal Unique machen Java Basics - Anfänger-Themen 20
X Wenn Exception dann nochmal try. Java Basics - Anfänger-Themen 7
R Nochmal Quaxli Spieletutorial ;) Java Basics - Anfänger-Themen 9
V Nochmal Hilfe - Replace Methode Java Basics - Anfänger-Themen 2
T Override klappt nochmal wie? Java Basics - Anfänger-Themen 3
Haubitze_Broese Methode am ende nochmal startet? Java Basics - Anfänger-Themen 8
D Ausgabe sauber formatieren *bitte nochmal reinschaun* Java Basics - Anfänger-Themen 7
D C0 und C1 Test nochmal Java Basics - Anfänger-Themen 9
B könnte nochmal jemand über mein Projekt schauen? Java Basics - Anfänger-Themen 4
C Nochmal zu lokale Einstellungen Java Basics - Anfänger-Themen 2
G nach Thread.start(); nochmal start(); aufrufen geht nicht Java Basics - Anfänger-Themen 4
S Fehler durch Exception beheben und nochmal versuchen Java Basics - Anfänger-Themen 4
U Nochmal was zum Date(); Java Basics - Anfänger-Themen 23
F nochmal Array Declaration Java Basics - Anfänger-Themen 2
G Nochmal vereinfacht - hoffe mer kanns nachvollziehen Java Basics - Anfänger-Themen 9
F Referenz Pointer oder doch nochmal neu suchen ? Java Basics - Anfänger-Themen 2
G Nochmal zweidimensionaler Vector Java Basics - Anfänger-Themen 10
ven000m Char einlesen, wie ging das nochmal? Java Basics - Anfänger-Themen 9
D Nochmal zu den dummen Eingaben über Tastatur Java Basics - Anfänger-Themen 15
B Nochmal ich/ Graphik wird nicht angezeigt ? Java Basics - Anfänger-Themen 12
G Nochmal Problem mit Kommunikation zwischen Klassen Java Basics - Anfänger-Themen 3
B nochmal ich / jdk1.5 Java Basics - Anfänger-Themen 5
S nochmal Taschenrechner ;) Java Basics - Anfänger-Themen 16
B Nochmal NoClassDefFoundError Java Basics - Anfänger-Themen 3
megachucky nochmal JDBC. komme nicht weiter. Java Basics - Anfänger-Themen 4
K nochmal Jtable Java Basics - Anfänger-Themen 5
E Synchronisierte Methoden vs. Synchronized(lockObject) Block Java Basics - Anfänger-Themen 7
S synchronisierte Methode mit warte bediengungen Java Basics - Anfänger-Themen 2
emreiu Methoden Rekursive Methoden Runter- & Hochzählen Java Basics - Anfänger-Themen 2
U Funktionale Interfaces mit mehreren abstrakten Methoden? Java Basics - Anfänger-Themen 8
MoxMorris Einige Methoden aus verschiedenen Klassen nacheinander auszuführen läuft seltsam Java Basics - Anfänger-Themen 2
J Argumente in Methoden übergeben Java Basics - Anfänger-Themen 1
XWing Methoden rückgabe Problem? Java Basics - Anfänger-Themen 6
Say Class scope und Instance scope und Getter nur selbstgeschrieben Methoden Java Basics - Anfänger-Themen 11
I Gleiche Klassen und Methoden in unterschiedlichen Projekten nutzen Java Basics - Anfänger-Themen 2
N Klassen Methoden anderer Klassen aufrufen Java Basics - Anfänger-Themen 4
Renjiroo Java Bmi Rechner mit Methoden Java Basics - Anfänger-Themen 4
frager2345 Thread - Methoden synchronized deklarieren Java Basics - Anfänger-Themen 10
M Designentscheidung von Attributen/Methoden im Falle von Vererbung Java Basics - Anfänger-Themen 8
berserkerdq2 Findet eine parallele Verarbeitung in Java bei Threads erst statt, wenn man die Methoden auch synchronized? Und wie sieht bei Conditions aus? Java Basics - Anfänger-Themen 8
Alen123 Erstes Arbeiten mit Methoden. Java Basics - Anfänger-Themen 5
berserkerdq2 Zwei Klassen Erben von der Klasse A, die eine Klasse kann ich an Methoden übergeben, die als Parameter A haben, die andere nicht? Java Basics - Anfänger-Themen 3
M Andere Methoden in anderen Klassen aufrufen Java Basics - Anfänger-Themen 11
L Methoden in anderen Klassen nutzen Java Basics - Anfänger-Themen 6
D Gerade oder ungerade Zahl mittels Methoden Java Basics - Anfänger-Themen 13
M Erklärung von Ausnahmebehandlung in Methoden Java Basics - Anfänger-Themen 13
S Methoden 2 non-static Methoden, trotzdem Fehler "non static method can not be referenced from a static context" Java Basics - Anfänger-Themen 9
L Rekursive Methoden Java Basics - Anfänger-Themen 14
X Wie erreiche ich, dass ein Robot weitere Attribute hat, die nicht materialisiert sind, sondern nur über get/ set-Methoden simuliert sind? Java Basics - Anfänger-Themen 1
C Problem mit mehreren Methoden + Scanner Java Basics - Anfänger-Themen 5
R Frage zu Methoden (Rückgabewert u. ohne.) Java Basics - Anfänger-Themen 2
W Verschiedene Methoden in einer Klasse in der Main aufrufen? Java Basics - Anfänger-Themen 8
W Methoden aufrufen - auch klassenübergreifend? Java Basics - Anfänger-Themen 9
Kotelettklopfer Methoden nicht aufrufbar Java Basics - Anfänger-Themen 34
R Schulaufgabe, Bruache Hilfe mit non-static Methoden Java Basics - Anfänger-Themen 2
S Vererbung Abstrakte Methoden: Wozu das Ganze?! Java Basics - Anfänger-Themen 7
S abstrakte methoden in subclass? Java Basics - Anfänger-Themen 7
S Methoden - Warum int wenn auch void? Java Basics - Anfänger-Themen 3
H Kann man Methoden öfter aufrufen? Java Basics - Anfänger-Themen 2
CptK Interface Functional interface mit mehreren Methoden Java Basics - Anfänger-Themen 6
P Objekt in mehreren Methoden verwenden. Java Basics - Anfänger-Themen 3
M Aufruf von statischen Methoden einer anderen Klasse Java Basics - Anfänger-Themen 15
lougoldi Verkettung von Methoden und Konstruktoren Java Basics - Anfänger-Themen 4
Zeppi OOP Methoden mit einander Verknüpfen Java Basics - Anfänger-Themen 6
A Löschen von Leerzeichen in einem char array ohne methoden Java Basics - Anfänger-Themen 6
A Parametar übergabe zwischen Methoden Java Basics - Anfänger-Themen 26
D Methoden nach einer bestimmten Reihenfolge ausführen. Java Basics - Anfänger-Themen 20
P Wie rufe ich Methoden mit einer Referenz auf eine Klasse||Objekt auf Java Basics - Anfänger-Themen 4
O Attribute die Methoden zählen Java Basics - Anfänger-Themen 5
M Bräuchte Hilfe bei diesen Methoden Java Basics - Anfänger-Themen 4
G Methoden Methoden mit versch. Datentypen Java Basics - Anfänger-Themen 1
T Ich habe eine Variabel die nicht Methoden übergreifend ist. Kann mir jemand Helfen :) Java Basics - Anfänger-Themen 5
Junger_Basileus Celsius -> Fahrenheit / Strukturierung in statischen Methoden Java Basics - Anfänger-Themen 7
J Verschachtelte Methoden Java Basics - Anfänger-Themen 9
H Methoden in anderen Methoden aufrufen Java Basics - Anfänger-Themen 6
Kawastori Hilfe bei Methoden Übung Java Basics - Anfänger-Themen 6
veryck Methoden Rekursive Methoden mit Rückgabeparameter Java Basics - Anfänger-Themen 9
C Methoden können nicht auf Instanzvariable der Klasse zugreifen Java Basics - Anfänger-Themen 3
P Methoden aufrufen - Fehler Java Basics - Anfänger-Themen 20
M konzeptuelle Frage: In welcher Klasse definiert man am Besten Methoden, die die Kommunikation mit dem User regeln? Java Basics - Anfänger-Themen 8
C eigene Methoden erstellen (Instanzmethoden) Java Basics - Anfänger-Themen 7
P Klasse hat keinen Zugriff auf getter/setter-Methoden eines Objektes Java Basics - Anfänger-Themen 9
B Methoden Methoden haben kein Zugriff auf variablen Java Basics - Anfänger-Themen 4
M Gettter/Setter Methoden Klassenfelder kapselung und zugriff? Java Basics - Anfänger-Themen 1
C Fernseher-Aufgabe (Methoden, Klassen und Objekte) Java Basics - Anfänger-Themen 63
C Taschenrechner (switch) in Taschenrechner mit Methoden umwandeln Java Basics - Anfänger-Themen 115
H Methoden in großen Klassen gruppieren oder auslagern? Java Basics - Anfänger-Themen 10
G Generics Methoden Java Basics - Anfänger-Themen 7
L Test-Methoden schreiben Java Basics - Anfänger-Themen 13
S throws bei Methoden Java Basics - Anfänger-Themen 4
L Best Practice Code Refactoring für Methoden mit fast gleicher Aufbau Java Basics - Anfänger-Themen 6
I Greedy Methode Methoden nutzen Java Basics - Anfänger-Themen 3
C Methoden-Parameter ist Interface Java Basics - Anfänger-Themen 5
A Klassen und methoden Java Basics - Anfänger-Themen 15
S Übergabe von Arrays an Methoden Java Basics - Anfänger-Themen 20
L Methoden Wie Löse ich ext Methoden Aufruf Fehler? Java Basics - Anfänger-Themen 3
A Bankweverwaltung mit Klassen und Methoden Java Basics - Anfänger-Themen 14
B Methoden Ausgeben Aufgabe Java Basics - Anfänger-Themen 15

Ähnliche Java Themen

Neue Themen


Oben