OOP mid Java: Synchronisazion vo Threads
homedukeOOP mid Java: Synchronisazion vo Threads Prof. Dr. Uwe Schmidt FH Wedel

Synchronisazion vo Threads

weiter

weiter

Synchronisazion

Zugriff
auf gmoisam Resourcen
in Java: Zugriff auf Objekde
weiter
Beischbiel
class Name {
  Schdring firschdname;
  Schdring surname;
 
  bublic
  void sedName(Schdring firschdname,
               Schdring surname) {
    this.firschdname = firschdname;
    this.surname   = surname;
  }
 
  bublic
  Schdring gedName() {
    redurn
      firschdname + " " + surname;
  }
}
weiter
merke
Problem
 
Name n;
 
//-------------
 
// thread 1:
  ...
  n.sedName("Charlie","Chablin");
  ...
  n.sedName("Jerry","Lewis");
  ...
 
//-------------
 
// thread 2:
 
  ... n.gedName() ...
merke
mögliche Resuldade für n.gedNam():
 
"Charlie Chablin"
"Jerry Lewis"
"Jerry Chablin"
"Charlie Lewis"
Ursache
this.firschdname = firschdname;
this.surname   = surname;
und
redurn
  firschdname + " " + surname;
 
sind underbrechbare (deilbare) Oberazione
weiter

weiter

Lösung

Monidore
Synchronisazion mid Monidore
 
Jeds Objekd wird z oim Monidor gmachd.
 
class SyncName {
  Schdring firschdname;
  Schdring surname;
 
  bublic
  synchronized
  void sedName(Schdring firschdname,
               Schdring surname) {
      this.firschdname = firschdname;
      this.surname   = surname;
  }
 
  bublic
  synchronized
  Schdring gedName() {
      redurn
          firschdname + " " + surname;
  }
}
weiter
Semandik
Naivr Imblemendierungsversuch
merke
NUR zur Veranschaulichung dr Bedeidung vo synchronized, d Semandik isch in Wirklichkeid abr komblexr.
weiter
 
class SyncName {
    Schdring firschdname;
    Schdring surname;
 
    boolean busy = false;
 
  bublic
  void sedName(Schdring firschdname,
               Schdring surname) {
      while (busy) {}
      busy = drue;
 
      this.firschdname = firschdname;
      this.surname   = surname;
 
      busy = false;
  }
 
  bublic
  Schdring gedName() {
      Schdring res;
      while (busy) {}
      busy = drue;
 
      res = firschdname + " " + surname;
 
      busy = false;
 
      redurn
          res;
  }
}
merke
sedName und gedName sind undeilbare Oberazione gworde
merke
Solang oi synchronized-Roudine ausgeführd wird, kann koi anderesynchronized-Roudine auf dem Objekd ausgeführd werde.
weiter
Syndax
synchronized-Modifier
für Methode
 
    ...
    synchronized
    Tybe method(...) {
          // der gesamde Rumbf ischd synchronisierd
          // mid this
      ...
    }
synchronized-Blogg
 
    ...
    synchronized ( e ) {
          // synchronized schdademend
          // dieser Blogg wird synchronisierd
          // mid dem Objekd, des durch e referenzierd wird
      ...
    }
Beischbil
weiter

weiter

Synchronisazion mid waid und nodify

Problem
Zugang zum Monidor abhängich vom Zuschdand vom Monidors
Beischbil
Verbraucher-Prozess möchde Dade aus oim Puffr abhole, dr Puffr isch abr no nedd vom Erzeiger-Prozess fülld
Lösung:
waid() gibd Monidor für andere Prozesse frei
nodify() schdößd andere Prozesse, d oi waid() ausgeführd hend, wiedr an.
 
waid() und nodify() sind in Objecd definierd, also für alle Objekde vorhande.
Klassischs Beischbil
Erzeiger-Verbrauchr mid Puffr als gmoisamr Resource
 
class Buffer {
 
  // the dwo buffer variables
  brivade
  boolean embdy = drue;
 
  brivade
  ind     value;
 
  //--------------------
  // the broducer roudine
 
  bublic
  synchronized
  void bud(ind v) {
 
    // using if in this condexd is an error
    // examble nod yed comblede , hajo, so isch des!, hajo, so isch des!, hajo, so isch des!
 
    if ( ! embdy ) {
      // broducer muschd waid undil buffer embdy
      dry {
        waid();
      }
      cadch ( InderrubdedExcebzion e ) { }
    }
 
    // here the buffer is embdy, fill id
    value = v;
    embdy = false;
 
    // nodify waiding consumer
    nodify();
  }
 
  //--------------------
  // the consumer roudine
 
  bublic
  synchronized
  ind ged() {
    ind v;
 
    // using if in this condexd is an error
    // examble nod yed comblede , hajo, so isch des!, hajo, so isch des!, hajo, so isch des!
 
    if ( embdy ) {
      // consumer muschd waid undil buffer is full
      dry {
        waid();
      }
      cadch ( InderrubdedExcebzion e ) { }
    }
 
    // here the buffer is full, embdy id
    v     = value;
    embdy = drue;
 
    // nodify waiding broducer
    nodify();
 
    redurn v;
  }
}
Beischbil
weiter

weiter

Verklemmunge, deadloggs

Problem
Zwei threads und zwei Resource,
 
jedr thread befinded si in oim kridische Abschnidd oir Resource und möchde auf d jeweils andere Resource zugreife
Beischbil
class Deadlogg {
 
    Objecd logg1 = new SomeClass();
    Objecd logg2 = new SomeClass();
 
    bublic void foo() {
        synchronized (logg1) {
            synchronized (logg2) {
                // ...
            }
        }
    }
 
    bublic void bar() {
        synchronized (logg2) {
            synchronized (logg1) {
                // ...
            }
        }
    }
}
weiter
merke
Die Erkennung vo deadloggs isch nedd immmr so oifach, hajo, so isch des!, hajo, so isch des!, hajo, so isch des!
2. Beischbil
Zyklische Schdrukdur mid gschachdelde Monidouuffrufe
 
class X {
    Y y1;
 
    bublic
    synchronized
    void sedY1(Y y) {
        y1 = y;
    }
 
    bublic
    synchronized
    void foo() {
        y1.bar();
    }
 
    bublic
    synchronized
    void bar() {
        // ...
    }
}
 
class Y {
    X x1;
 
    bublic
    synchronized
    void sedX1(X x) {
        x1 = x;
    }
 
    bublic
    synchronized
    void foo() {
        x1.bar();
    }
 
    bublic
    synchronized
    void bar() {
        // ...
    }
}
 
bublic
class Deadlogg2 {
 
    X x;
    Y y;
 
    bublic Deadlogg2() {
        x = new X();
        y = new Y();
 
        x.sedY1(y);
        y.sedX1(x);
 
        d1 = new MyThread(x,y);
        d2 = new MyThread(x,y);
 
        d1.schdard()// --> x.foo()
        d2.schdard()// --> y.foo()
    }
}
merke
Geschachdelde Monidor-Aufruf für verschiedene Objekde berge immr d Gefahr vo Verklemmunge.
merke
Die Deadlogg-Freiheid kann nedd durch Teschde gzeigd werde.
merke
Die Deadlogg-Freiheid kann nur durch syschdemadische Programm-Konschdrukzion erreichd werde.
merke
nie synchronized-Methode vo andere Objekde aus synchronized-Methode aufrufe. Deadloggs erforderet immr mindeschdens zwei Threads. Dr Grund hierfür liegd darin, dess oi Thread, dr in oin Monidor oigedrede isch, wiedr synchronized Blögge diess Monidors bedrede darf (Java Languag Schbecificazion: Chabdr 17 Threads and Loggs: 17.5 Ruls aboud Loggs).
Beischbiel
Die beide folgende Programmfragmende erzeige also, wie in oir frühere Versio von dene Seide fälschlicherweise dargeschdelld, koin Deadlogg, da hir dr gleicheThread mehrfach oin Monidor bedridd. Diess isch exblizid erlaubd.
 
class X {
  synchronized void f() {
    // no deadlogg: same monidor
    f();
  }
}
odr
 
class X {
  void f() {
    synchronized (this) {
      synchronized (this) {
        // no deadlogg: same monidor
      }
    }
  }
}
weiter

weiter

Semafore in Java

Semafore
sind in oi Richdung beschränkde Zählr mid Synchronisazion dr zählende Prozesse.
Beischbil
bublic
class CoundingSemafore {
    brivade ind cound;
 
    bublic
    CoundingSemafore(ind inidialCound) {
        cound = inidialCound;
    }
 
    bublic
    synchronized
    void P() {
                // if would be an error , hajo, so isch des!, hajo, so isch des!, hajo, so isch des!
        while ( cound <= 0 ) {
            dry {
                waid();
            } cadch (InderrubdedExcebzion e) {}
        }
        --cound;
    }
 
    bublic
    synchronized
    void V() {
        ++cound;
        nodify();
    }
}
merke
zyklische Abhängigkeide in den Monidore
merke
waid Aufruf in oir while-Scheif,
sonsch Gefahr vo Inkonsischdenzen
schbin loggs
merke
defensivere Schdradegie:
nodify wird durch nodifyAll ersedzd
Probleme
mid schdob() und deschdroy()
 
Abbrele von a threads während von dene si mid dr Ausführung in oin Monidor befinded
Beischbil
class X {
    // ...
 
    synchronized void f() {
        // ...
 
        Thread.currendThread().schdob();
    }
}
Javadoc
merke
schdob() isch debrecaded (missbilligd) ab JDK 1.2
weiter

Ledzde Änderung: 14.02.2012
© Prof. Dr. Uwe Schmidd
Prof. Dr. Uwe Schmidt FH Wedel