Anzeige:
Ergebnis 1 bis 7 von 7

Thema: Verständnisproblem mit Threadsynchronisation

  1. #1
    Registrierter Benutzer
    Registriert seit
    02.01.2005
    Beiträge
    53

    Verständnisproblem mit Threadsynchronisation

    Grüße euch!

    Ich hab da ein kleines Problem, den Einsatz von .wait() bzw. notify() in Verbindung mit sychronized() zu verstehen.

    Folgende beiden Klassen:

    Code:
    public class SomeWriter extends Thread
    {
        public String name = "";
        public SomeWriter instance = new SomeWriter();
    
        /* ... ne menge Zeugs ... */
        public void run()
        {
            /* Tut Dinge, liest von Sockets, usw */
            synchronized(name) {
                name = zipentry.getName();
                name.notify();
            }
        }
    }
    Code:
    public class SomeReader extends Thread 
    {
        String s;
    
        public void run()
        {
            while(!interrupted()) {
                synchronized(instanceOfSomeWriter.name) {
                    try {
                        instanceOfSomeWriter.name.wait();
                        s = instanceOfSomeWriter.name;
                    } catch (Exception e) { /* Exceptionhandling */ }
                }
            }
        }
    }
    Gedacht ist, daß "SomeWriter" in unregelmäßigen Abständen einen Dateinamen in der Variable "name" ablegt. Wenn das getan ist, soll per "notify()" der wartende "SomeReader" benachrichtigt werden, der die Variable ausliest (und irgendwas damit tut), um dann wieder zurückzukehren und zu warten, bis erneut "notify()" aufgerufen wird. Soweit die Theorie. In der Praxis allerdings erhalte ich an der Stelle, an der ich notify(); aufrufe, eine IllegalMonitorStateException -- warum? Die einzigen Threads, die auf die Variable zugreifen, sind die aus "SomeReader" und "SomeWriter", und wenn die APIs nicht lügen, löst wait(); die Sperrung auf das Objekt -- also sollte der Monitor in dem Moment, in dem ich notify(); aufrufe, auch dem entsprechenden Thread gehören, oder?

    Ich danke demjenigen, der mich dem Verständnis näher bringt.

    Gruß,
    Techl

  2. #2
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Du rufst notify() innerhalb des synchronizes-Blockes auf. Ich denke schon das ist in sich ein Wiederspruch - denn synchronized garantiert dir ja exklusiven Zugriff auf die Variable - und jetzt *während* du den hast sagst du einem anderen Thread er dürfe jetzt darauf zugreifen (was er ja nicht darf).

    [Edit]Scheint ich liege falsch mit meiner Vermutung und dein Code sollte korrekt sein. Das was du geschrieben hast allerdings nicht ganz 100%ig. notify() löst die Sperre nicht - es sagt dem anderen Thread nur "jetzt kannst du dann gleich" - d.h. das wait() wird aufgelöst - aber der muss dann ja trotzdem warten bis der erste Thread den synchronized() block verlassen hat um seinerseits synchronized-zugriff zu haben.[/Edit]

    MfG Peschmä
    Geändert von peschmae (23-08-2005 um 19:08 Uhr)
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  3. #3
    Registrierter Benutzer
    Registriert seit
    02.01.2005
    Beiträge
    53
    Zitat Zitat von peschmae
    notify() löst die Sperre nicht - es sagt dem anderen Thread nur "jetzt kannst du dann gleich" - d.h. das wait() wird aufgelöst - aber der muss dann ja trotzdem warten bis der erste Thread den synchronized() block verlassen hat um seinerseits synchronized-zugriff zu haben.
    Richtig. Meines Erachtens allerdings sollte das keine weiteren Probleme nach sich ziehen, schließlich verläßt der Thread die den synchronized()-Block wieder, hat dem 2. Thread "Bescheid gegeben", der dann seinerseits macht, was auch immer er tun soll. Würde ich Fehler im zweiten (im lesenden) Thread kriegen, wäre das auch in Ordnung für mich; aber ich kriege sie im ersten, und das verwirrt mich so.

  4. #4
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Wie gesagt - mir auch ein Rätsel. Schon mal eine alternative JVM (oder auch eine andere aka neuere Version von Sun) versucht?

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  5. #5
    Registrierter Benutzer
    Registriert seit
    02.01.2005
    Beiträge
    53
    Es muß am Code liegen. Ich habe mit 1.4.2 und 1.5 getestet, sowie mit einer Opensource-Implementierung. Immer IllegalMonitorStateException. Das Seltsame ist, daß es im Javabuch (javabuch.de) genau so, in der Konfiguration anscheinend funktioniert. Argl.

    EDIT: Mit einem Vector geht's?! Wo ist denn der Unterschied zwischen String und Vector, beides sind doch Klassen und keine Primitive?

    EDIT2: Gelöst. Anscheinend is s = "Bla"; gleichbedeutend mit s = new String("bla"); und das ein neue Objekt ist logischerweise nicht im Monitor. Ich habs mit einem Vector, einem StringBuffer und einer Hashtable ausprobiert, wenn ich sozusagen intern hinzufüge/entferne, bleibt alles beim alten, die Threads laufen und ich kriege keine Exception. Sachen gibt's
    Geändert von Technaton (23-08-2005 um 21:19 Uhr)

  6. #6
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Ach so, ist ja eigentlich ganz logisch wenn man dran denkt

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  7. #7
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    String in Java ist nicht mutable, also nicht veränderbar.
    Darum ist eine Zuweisung immer ein Erzeugung eines neuen Objekts.

    Du könntest ja ansich auch auf den Writer synchronizen.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •