tutorials.de Buch-Aktion 05/2012
Like Tree1Danke
  • 1 Beitrag von Tomek_FFM
ERLEDIGT
NEIN
ANTWORTEN
11
ZUGRIFFE
979
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Steve222 Steve222 ist offline Mitglied Bronze
    Registriert seit
    Mar 2007
    Ort
    Rheinland
    Beiträge
    46
    Hallo allerseits,

    kann mir jemand verständlich erklären, warum der folgende Code
    NICHT verhindert, dass z.B. "X Y Y X" ausgegeben wird?
    Ich dachte run() mit seinem write() Aufruf wird NICHT von einem
    anderen thread gestört.


    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    public class Buchstabe extends Thread {
    private String name;
     
    public synchronized void run() { write(); }     
     
    public Buchstabe(String name) { this.name = name; }
     
    public void write() {
        System.out.print(name);
        System.out.print(name);
    }
        public static void main(String[] args) {
            new Buchstabe(" X ").start();
            new Buchstabe(" Y ").start();
        }
    }


    Ich Voraus schon vielen Dank für Eure Hilfe.

    Viele Grüße

    Steve222
     

  2. #2
    Avatar von zerix
    zerix zerix ist offline Hausmeister
    tutorials.de Moderator
    Registriert seit
    May 2005
    Beiträge
    4.335
    Hallo,

    weil es sich hier um zwei unterschiedliche Objekte handelt.
    Es kann nur innerhalb eines Objektes synchronisiert werden. Das wäre ja schlimm, wenn es klassenweit wäre.

    Wenn du das testen möchtest, musst du zwei Threads anlegen, die gleichzeitig versuchen die Methode auf einem Object aufzurufen.


    Gruß

    Sascha
     
    Es ist schwer Allwissend zu sein. Aber ich komme damit klar. ;-)

  3. #3
    Tomek_FFM Tomek_FFM ist offline Mitglied Silber
    Registriert seit
    Mar 2007
    Ort
    Frankfurt am Main
    Beiträge
    67
    Statt

    Code java:
    1
    
    public synchronized void run() { write(); }

    kannst du über ein global verfügbares Objekt (z.B. eine Klasse) synchronisieren:

    Code java:
    1
    2
    3
    4
    5
    
    public void run() {
        synchronized (Buchstabe.class) {
            write();
        }
    }
    Steve222 bedankt sich. 

  4. #4
    Kai008 Kai008 ist offline Mitglied Brillant
    Registriert seit
    May 2008
    Ort
    Brunn/Geb. (Niederösterreich)
    Beiträge
    944
    Blog-Einträge
    1
    Oder einen statischen ReentrantLock anlegen, und lock bzw. unlock aufrufen.
     
    Mein kleiner webstart Projektplaner:
    http://178.77.101.236/ppws/
    Ideen, Verbesserungsvorschläge, Bugsmeldungen und allg. Kritik erwünscht und erbeten.

    Danke. :)

  5. #5
    Steve222 Steve222 ist offline Mitglied Bronze
    Registriert seit
    Mar 2007
    Ort
    Rheinland
    Beiträge
    46
    Zitat Zitat von zerix Beitrag anzeigen
    Hallo,

    weil es sich hier um zwei unterschiedliche Objekte handelt.
    Es kann nur innerhalb eines Objektes synchronisiert werden. Das wäre ja schlimm, wenn es klassenweit wäre.

    Wenn du das testen möchtest, musst du zwei Threads anlegen, die gleichzeitig versuchen die Methode auf einem Object aufzurufen.


    Gruß

    Sascha
    Hallo Sascha
    und Danke. Ich verstehe es jedoch nicht wirklich.
    Dass es sich um zwei Thread Objekte handelt ist/war mir soweit klar.
    Warum schützt das Schlüsselwort "synchronized" vor run() nicht
    davor, dass die Ausführung von run(), und alles was innerhalb run() passiert [z.B. der Aufruf und Ausführung von write() ], unterbrochen wird.
    Warum wird write() gestört, obwohl es sich innerhalb "synchronized run()" befindet?

    Was bedeutet
    Zitat Zitat von zerix Beitrag anzeigen
    Es kann nur innerhalb eines Objektes synchronisiert werden.
    und
    Zitat Zitat von zerix Beitrag anzeigen
    ...die Methode auf einem Object aufzurufen.....
    Nicht gerade Klarheit bringt, dass ein Thread auch ein Objekt ist bzw. sein kann und umgekehrt.

    Steve222
     

  6. #6
    Kai008 Kai008 ist offline Mitglied Brillant
    Registriert seit
    May 2008
    Ort
    Brunn/Geb. (Niederösterreich)
    Beiträge
    944
    Blog-Einträge
    1
    Ich denke, dass er meint, dass die Methode nur Instanceweit syncronisiert ist, also musst du write static machen und ihm dem Namen übergeben, damit es hinhaut.
     
    Mein kleiner webstart Projektplaner:
    http://178.77.101.236/ppws/
    Ideen, Verbesserungsvorschläge, Bugsmeldungen und allg. Kritik erwünscht und erbeten.

    Danke. :)

  7. #7
    Tomek_FFM Tomek_FFM ist offline Mitglied Silber
    Registriert seit
    Mar 2007
    Ort
    Frankfurt am Main
    Beiträge
    67
    Die Zeile

    Code java:
    1
    2
    3
    
    public synchronized void run() { 
      write(); 
    }

    ist das gleiche wie

    Code java:
    1
    2
    3
    4
    5
    
    public void run() { 
      synchronized(this) {
        write(); 
      }
    }

    Dadurch synchronisierst du über die jeweilige Instanz des Threads "Buchstabe". Da du nun 2 Threads/Instanzen erzeugst, ist der Lock/Monitor in beiden Threads verschieden. Was dir eben fehlt, ist ein Lock/Monitor, der in beiden Instanzen gleich ist.
     

  8. #8
    Avatar von zerix
    zerix zerix ist offline Hausmeister
    tutorials.de Moderator
    Registriert seit
    May 2005
    Beiträge
    4.335
    Ich sehe ja jetzt erst, dass bei dir Buchstabe von Thread abgeleitet ist.

    Mal ein Beispiel wie das funktioniert, was du gebaut hast (nur Buchstabe nicht als Thread).
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
     
    public class SynchonizedExample {
     
        
        
        public synchronized void write(){
            System.out.println("A");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("B");
        }
        
        public static void main(String[] args) {
            final SynchonizedExample example = new SynchonizedExample();
            
            new Thread(){
                public void run() {
                    
                    example.write();
                };
            }.start();
            
            example.write();
        }
        
    }

    Also wenn das synchronized im Methoden-Header steht, wartet die Methode nur, wenn sie nochmal auf dem gleichen Object aufgerufen wird.

    Gruß

    Sascha
     
    Es ist schwer Allwissend zu sein. Aber ich komme damit klar. ;-)

  9. #9
    Steve222 Steve222 ist offline Mitglied Bronze
    Registriert seit
    Mar 2007
    Ort
    Rheinland
    Beiträge
    46
    Zitat Zitat von Tomek_FFM Beitrag anzeigen
    ...
    Dadurch synchronisierst du über die jeweilige Instanz des Threads "Buchstabe". Da du nun 2 Threads/Instanzen erzeugst, ist der Lock/Monitor in beiden Threads verschieden. Was dir eben fehlt, ist ein Lock/Monitor, der in beiden Instanzen gleich ist.
    Es ist/war mir bekannt, dass der synchronized-Bereich durch synchronized(this) innerhalb der run() Definion notiert werden
    kann und dass das gleiche ist.
    Ich hatte gedacht, dass "synchronized(this) { <irgendein Code C1> }" dafür sorgt, dass <irgendein Code C1> ungestört
    ausgeführt wird.
    Dann ist es wohl der Scheduler, der write unterbricht und dafür verantwortlich ist, dass Ausgaben wie "X Y Y X" möglich sind!?

    Du meinst höchstwahrscheinlich, dass die beiden Threads/Instanzen von des Threads "Buchstabe" eine gemeinsame
    Synchronisationsvariable, sozusagen den SELBEN Lock/Monitor brauchen, über die/den sie miteinander kommunizieren.
    können!?

    Viele Grüße
    Steve222
     

  10. #10
    Tomek_FFM Tomek_FFM ist offline Mitglied Silber
    Registriert seit
    Mar 2007
    Ort
    Frankfurt am Main
    Beiträge
    67
    Zitat Zitat von Steve222 Beitrag anzeigen
    Du meinst höchstwahrscheinlich, dass die beiden Threads/Instanzen von des Threads "Buchstabe" eine gemeinsame
    Synchronisationsvariable, sozusagen den SELBEN Lock/Monitor brauchen, über die/den sie miteinander kommunizieren.
    können!?
    Genau, denn mit synchronized(this) hast du 2 verschiedene Locks, die nichts miteinander zu tun haben!
     

  11. #11
    Painer Painer ist offline Rookie
    Registriert seit
    Mar 2004
    Ort
    Hamburg
    Beiträge
    9
    Ich weiß nicht, ob das jetzt schon komplett klar geworden ist: Die Angabe synchronized verhindert nicht dass eine Methode unterbrochen wird. Der Scheduler unterbricht die Methode trotzdem. Jedoch kann kein anderer Thread einen Block betreten, der über das gleiche Objekt synchronisiert ist. Diese Threads müssen warten bis der erste den Block verlassen hat. Trotzdem wird zu anderen Threads, die nichts mit Synchronisation über das Objekt zu tun haben, weiterhin ausgeführt, bzw. zu denen geschaltet.
     

  12. #12
    Kai008 Kai008 ist offline Mitglied Brillant
    Registriert seit
    May 2008
    Ort
    Brunn/Geb. (Niederösterreich)
    Beiträge
    944
    Blog-Einträge
    1
    Jep. Natürlich unterbricht der Sheduler, sonst wäre es ja Singletasking. Und bei neueren OSes bekommen die Tasks die Bearbeitungszeiten ect. von der CPU, da sonst ein Programm den Rechner lahmlegen könnte.
    Geändert von Kai008 (27.04.10 um 02:24 Uhr)
     
    Mein kleiner webstart Projektplaner:
    http://178.77.101.236/ppws/
    Ideen, Verbesserungsvorschläge, Bugsmeldungen und allg. Kritik erwünscht und erbeten.

    Danke. :)

Ähnliche Themen

  1. Frage zu synchronized
    Von M_Kay im Forum Java
    Antworten: 9
    Letzter Beitrag: 10.07.09, 11:58
  2. Schlüsselwort synchronized - 2 Varianten
    Von Klein0r im Forum Java
    Antworten: 1
    Letzter Beitrag: 08.05.08, 00:22
  3. Antworten: 0
    Letzter Beitrag: 16.10.07, 20:00
  4. synchronized, wait, notify
    Von PeteProgram im Forum Java
    Antworten: 4
    Letzter Beitrag: 20.06.07, 12:37
  5. static Methoden und synchronized
    Von kleinis_1 im Forum Java
    Antworten: 2
    Letzter Beitrag: 23.12.05, 14:30