• Keine Ergebnisse gefunden

Conditional Critical Regions

N/A
N/A
Protected

Academic year: 2021

Aktie "Conditional Critical Regions"

Copied!
16
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Info B VL 17: Deadlocks

Objektorientiere Programmierung in Java 2003

Ute Schmid (Vorlesung) Elmar Ludwig ( ¨Ubung)

FB Mathematik/Informatik, Universit¨at Osnabr¨uck

(2)

Conditional Critical Regions

Konzept von Hoare, allgemeiner als Semaphoren.

Es existiert ein kritischer Abschnitt, wobei der Zugang durch eine Bedingung geschützt wird.

Typischerweise mit while-Schleife realisiert.

Würde man if anstelle von while verwenden, so würden aufgeweckte Threads nicht merken, dass ein anderer Thread die condition verändert hat.

(Während man schläft können andere arbeiten.)

synchronized(o) { synchronized(o) {

while (!condition ) { // condition == false

// ... // tu was

(3)

Monitore, CCRs, Semaphoren

Monitor: Ein Java-Objekt, das den Zugang zu synchronisierten (Instanz)-Methoden/Blöcken kontrolliert.

Conditional Critical Region: kritischer Abschnitt (in einem synchronisierten Block), bei dem auf Zugang gewartet wird (wait()), solange bis eine Bedingung erfüllt ist. Ein anderer Block macht die Bedingung wahr und gibt den kritischen Abschnitt frei (notify(),

notifyAll()).

Semaphoren: Sperren und Freigeben, realisiert durch Zähler und Warteschlange. Spezielle Technik, um

CCRs zu realisieren.

(4)

Deadlocks

Eine Situation in der zwei oder mehr

Prozesse/Threads nicht weiterarbeiten können, weil jeder darauf wartet, dass mindestens ein anderer etwas bestimmtes erledigt, heisst Deadlock.

Standardbeispiel: Dining Philosophers

(5)

Dining Philosophers

Wenn alle fünf Philosophen zur Gabel zu ihrer Rechten greifen, entsteht ein Deadlock!

Zweites Problem: Aushungern eines Philosophen (die anderen sind immer schneller beim Zugreifen). Kann mit Semaphoren oder kritischen Abschnitten alleine nicht verhindert werden. Java erlaubt immer einem beliebigen Thread, dass er zum Zug kommt.

(6)

Nicht Verklemmungsfrei

// Anzahl von Gabeln ist 5.

// Jede Gabel sei eine Semaphore, // die mit 1 initialisiert wird.

// F¨ur einen Philosophen i:

while(true) { think();

gabel[i].P();

gabel[(i+1)%anzahl].P(); // wg. i+1 gr¨oßer 4 eat();

gabel[i].V();

gabel[(i+1)%anzahl].V();

}

(7)

Bedingungen für Deadlocks

Exklusive Belegung: Betriebsmittel sind entweder von genau einem Prozess belegt oder frei. (eine Gabel)

Belegen und Warten: Prozesse belegen Betriebsmittel und warten während der Belegung auf die Zuteilung weiterer Betriebsmittel. (linke und rechte Gabel)

Kein zwangsweises Freigeben: Betriebsmittel können nicht entzogen werden, sondern müssen vom Prozess zurückgegeben werden (Hinlegen einer Gabel)

Zyklische Wartebedingung: Es muss einen Ring aus zwei oder mehr Prozessen bestehen, bei der jeder Prozess auf ein von einem anderen Prozess aus der Kette belegtes Betriebsmittel wartet. (5 Philosophen)

(8)

Beispiellösungen

Lösung mit globaler Kontrolle: Manager.java

Bedingter Zugriff auf Gabeln: Philosopher2.java

(9)

Deadlocks durch falsche Anordnung

// When two threads try to lock two objects, deadlock can occur // unless they always request the locks in the same order.

final Object resource1 = new Object(); // Here are two objects to lock final Object resource2 = new Object();

Thread t1 = new Thread(new Runnable() { // Locks resource1 public void run() { // then resource2

synchronized(resource1) {

synchronized(resource2) { compute(); } }

} });

Thread t2 = new Thread(new Runnable() { // Locks resource2 public void run() { // then resource1

synchronized(resource2) {

synchronized(resource1) { compute(); } } }

});

t1.start(); // Locks resource1

t2.start(); // Locks resource2 and now neither thread can progress!

(10)

Threads: Ergänzungen

Threads können durch setDaemon(true) zu

Dämon-Threads gemacht werden: Der Interpreter wird beendet, wenn alle Nicht-Dämon-Threads beendet

sind.

Threads können Thread-Gruppen zugeordnet werden und dann gemeinsam behandelt werden. Ohne

explizite Angabe einer Gruppe gehört ein Thread zur Gruppe ‘System’.

(11)

Threads und Collections

Vordefinierte Klassen, die Collection, Set, List oder Map implementieren, haben in der Regel keine synchronized()-Methoden (z.B. ArrayList). Es können synchronisierte Wrapper-Objekte erzeugt

werden:

List synclist =

Collections.synchronizedList(list);

Map syncmap =

Collections.synchronizedMap(map);

(12)

Unterbrechen von Threads

Ordentliches Unterbrechen eines Threads durch interrupt().

wait() und sleep() erlauben einen Interrupt, also kann ein Thread nicht “mitten beim Arbeiten”

angehalten werden.

class T extends Thread { public void run() {

while(true) { // This thread runs until asked to stop

process(); // Do something

try { Thread.sleep(1000); } // Wait 1000 millisecs catch (InterruptedException e) { // Handle the interrupt

return;

} } }

(13)

Pipe-Ströme

Pipes werden benutzt, um von einem Thread erzeugte Daten einem anderen Thread zur Verfügung zu stellen.

Klassen PipedReader/PipedWriter (Character-Stream) bzw.

PipedInputStream/PipedOutputStream aus java.io

(14)

Beispiel (1)

Reverse Sort

Reverse Sort

Reverse

Reverse List of reversed

words

List of words List of reversed

sorted words

List of rhyming words

List of words List of rhyming

words

Code: RhymingWords.java

nutzt die verschieden kombinierbaren Komponenten und

(15)

Beispiel (2)

Ohne Pipe-Ströme müssen die Operationen Umdrehen, Sortieren, Umdrehen sequentiell

abgearbeitet werden, da jedes Zwischenergebnis

explizit, z. B. in einer Datei, gespeichert werden muss.

Mit Pipe-Strömen kann der Output einer Operation direkt an die nachfolgende Operation übergeben werden.

In der main-Methode wird ein Reader-Objekt erzeugt.

Die Ermittlung der reimenden Worte wird über den verschachtelten Methodenaufruf

reverse(sort(reverse(words))) realisiert.

Die Methoden reverse() und sort() arbeiten mit Threads und kommunizieren über Pipe-Ströme

(16)

Beispiel (3)

Ein PipeReader wird “auf” einem PipeWriter erzeugt:

Was auf den PipeWriter geschrieben wird, kann vom PipeReader gelesen werden!

Dazu gibt es (für die Thread-Objekte) einen

BufferedReader, der die Eingabe (aus einer Quelle, z.B. der Pipe) erhält, und einen PrintWriter, der die Ausgabe in eine Sink (z.B. Pipe) schreibt.

Referenzen

ÄHNLICHE DOKUMENTE

Mit dem Hauptsatz f¨ur endlich erzeugte Moduln ¨uber Hauptidealringen (Satz... Es

Schülerinnen und Schüler von Ludwigshafener Schulen, die noch ausgeliehene Schulbücher zurückgeben müssen, können dies in der Zeit von Montag, 28.. Juli 2014 jeweils von 9 bis 16

Dadurch ließen sich Namen und Adresse der Besitzerin in der Yorckstraße ausfindig machen, welche die KVD-Streife aufsuchte, um ihr den Geldbeutel zu übergeben. Die junge Frau

Wenn ich daran denke, wie viel mehr wir heute für Umweltschutz sensibilisiert sind als noch vor zehn Jahren, wenn ich die Rückkehr zur vollwertigen Kost beobachte Vollkornbrot

Am linken Bild (Abbildung 5.9 a) wurde die Probe im Phasenkontrast aufgenommen. Hier kann man eine leichte Subkornbildung erkennen. Aber nicht alles ist auf

Praktische Informatik 3: Funktionale Programmierung Vorlesung 5 vom 13.11.2018: Rekursive und

Wenn es große Kategorien von Bedürfnissen gibt, die alle oder viele Menschen teilen, dann koordiniert das auch die Erwartungen der Investoren, nicht nur dem Niveau nach wie bei

Die Tabletten – auch wenn sie sehr groß sind – bitte im Ganzen runterschlucken und keinesfalls kauen, lutschen oder vorher zerkleinern.. Schutz der Speiseröhre Diese recht