Nebenläufige Programmierung I

Ähnliche Dokumente
Nebenläufige Programmierung I

Thread-Synchronisation in in Java. Threads Wechselseitiger Ausschluss Bedingte Synchronisation Beispiel: Warteschlangen

Dr. Monika Meiler. Inhalt

Nebenläufige Programmierung in Java: Threads

Prozesse. Prozesse sind Programme. Prozesse können aus Unterprozessen bestehen. Prozesshierarchie Unterprozesse Threads

5. Threads, Serverprozesse und Benachrichtigungen

Klassen und ihre Beziehungen III: Mehrfache Vererbung, Rollen, Schnittstellen und Pakete

Vererbung. Martin Wirsing. Ziele. Vererbung

Parallele Prozesse. Prozeß wartet

Parallele und funktionale Programmierung Wintersemester 2015/ Übung Abgabe bis , 10:00 Uhr

Threading. Arthur Zaczek. Aug 2015

Ausnahmebehandlung in Java

Beispiel für überladene Methode

Java I Vorlesung Nebenläufigkeit

Programmierung mit Threads in Java

Neben der Verwendung von Klassen ist Vererbung ein wichtiges Merkmal objektorientierter

Synchronisation in Java. Invisible Web

Praktikum aus Softwareentwicklung 2, Stunde 5

2.2 Prozesse in Java

Vorlesung Informatik II

Parallele Prozesse Prozeß Parallele Prozesse verzahnte Prozesse Nebenläufige Prozesse: Threads Vorlesung Software-Entwicklung / Folie 131 Ziele:

EINFÜHRUNG IN DIE PROGRAMMIERUNG

Betriebssysteme. Wintersemester Kapitel 2 Prozess und Threads. Patrick Kendzo ppkendzo@gmail.com

Das Monitorkonzept Brinch-Hansen

Assoziation und Aggregation

Verteilte Systeme CS5001

Durch die Teil-von-Beziehung soll ausgedrückt werden, dass ein Objekt A als (physikalischer) Teil eines Objekts B angesehen wird. Insbesondere kann ei

Sequentielle Programm- / Funktionsausführung innerhalb eines Prozesses ( thread = Ausführungsfaden )

Soll die Programm-Ausführung nicht beendet werden, muss der Fehler abgefangen werden. NumberFormatException

Einstieg in die Informatik mit Java

12. Threads in Java. Sequentielle Abarbeitung (2) Beispiel: Thread (1) Sequentielle Abarbeitung (1)

Javakurs für Anfänger

Kapitel 9. Programmierkurs. Attribute von Klassen, Methoden und Variablen. 9.1 Attribute von Klassen, Methoden und Variablen

Vorlesung Informatik II

Verteilte Systeme. 2. Die Client-Server-Beziehung und daraus resultierende Techniken. 2.2 Nebenläufigkeitstechniken in Java

Universität Augsburg, Institut für Informatik Sommersemester 2001 Prof. Dr. Martin Ester 08. Oktober Klausur II

Kapitel 6. Vererbung

Einführung in die Programmierung mit Java

Nebenläufige Programmierung in Java

Vererbung. Gerd Bohlender. Institut für Angewandte und Numerische Mathematik. Vorlesung: Einstieg in die Informatik mit Java 23.5.

Java Concurrency Utilities

6. Tutorium zu Softwaretechnik I

Nebenläufigkeit mit Java

Exkurs: ANONYME KLASSEN. Techniken der Programmentwicklung Prof. Dr. Wolfgang Schramm

Vererbung, Polymorphie

Kapitel 6. Vererbung

Einführung Verteilte Systeme - Java Threads III -

Zur Erinnerung: Threads. Threadverwaltung. Threads: Prioritäten. Beispiel Flugbuchungsprogramm. Nichtdeterminismus

Motivation. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 20: Threads. Inhalt. Ein Beispiel zur Motivation

Kapitel 6. Vererbung

Einführung in die Programmierung mit Java

3 Objektorientierte Konzepte in Java

Innere Klassen in Java

Grundzüge der Programmierung. Wiederverwendung VERERBUNG

Funktionale und Objekt-Orientierte Programmierkonzepte

Thread-Konzept in objektorientierten Programmiersprachen. Threads. Threads in Java

Kapitel 4. Monitore und wechselseitiger Ausschluss

Einstieg in die Informatik mit Java

Java für Bauingenieure

1 Abstrakte Klassen, finale Klassen und Interfaces

Assoziation und Aggregation

Übung zu Grundlagen der Betriebssysteme. 10. Übung

Dezentrale Kontrolle: Aktive Objekte. Aktive Objekte Die Klasse AnimatorThread Aktivierung Objekte beobachten Die Java-Klasse Thread

Test-Driven Design: Ein einfaches Beispiel

16. Parallelität: Threads

Graphical User Interfaces

12 Abstrakte Klassen, finale Klassen und Interfaces

Klausur Software-Entwicklung März 01

Innere Klassen. Gerd Bohlender. Institut für Angewandte und Numerische Mathematik. Vorlesung: Einstieg in die Informatik mit Java

Java-Programmierung. Remote Method Invocation - RMI

Einstieg in die Informatik mit Java

Repetitorium Informatik (Java)

Versuchsziele Konzepte der parallelen Programmierung am Beispiel von Threads anwenden können. Einbau von Kontrollmechanismen mittels Semaphore.

Betriebssysteme G: Parallele Prozesse (Teil A: Grundlagen)

Einstieg in die Informatik mit Java

Probeklausur: Programmierung WS04/05

Algorithmen und Datenstrukturen

Programmieren in Java -Eingangstest-

Einstieg in die Informatik mit Java

Nebenläufigkeit mit Java

Universität Potsdam Institut für Informatik Sommersemester Programmierung. Lehrblatt Woche 11

Universität Karlsruhe (TH)

Einführung in die Informatik 1

Threads In dieser Übung beschäftigen wir uns mit der Realisierung von Threads in Java.

OpenMP - Threading- Spracherweiterung für C/C++ Matthias Klein, Michael Pötz Systemprogrammierung 15. Juni 2009

Systeme I: Betriebssysteme Kapitel 4 Prozesse. Wolfram Burgard

Deklaration einer Klasse Innere innerhalb Klassen einer in Ja anderen v a Klasse

Systeme I: Betriebssysteme Kapitel 4 Prozesse. Maren Bennewitz

Java Einführung Methoden in Klassen

Universität Karlsruhe (TH)

Einführung in die Programmierung Blockkurs Java

Javakurs FSS Lehrstuhl Stuckenschmidt. Tag 3 - Objektorientierung

Vorname: Nachname: Matrikelnummer: Klausur. Betriebssysteme

Th. Letschert OOP 2 2. Geheimnisprinzip und Sichtbarkeitsbeziehungen

Programmierkurs Java

Klausurvorbereitung VS1 (Prof. Brecht) (B0rg Edition)

Parallele Programmierung in Java

Prinzipien Objektorientierter Programmierung

Programmieren II. Innere Klassen. Heusch 10, Ratz 5.2.1, Institut für Angewandte Informatik

Institut für Programmierung und Reaktive Systeme 17. Juli Programmieren II. Übungsklausur

Transkript:

Nebenläufige Programmierung I Martin Wirsing in Zusammenarbeit mit Matthias Hölzl, Piotr Kosiuczenko, Dirk Pattinson 07/03 Ziele 2 Grundlegende Begriffe der nebenläufigen Programmierung verstehen lernen Nebenläufige Programme in Java schreiben lernen

Nebenläufige und verteilte Systeme 3 Ein System ist von seiner Umgebung abgegrenzte Anordnung von Komponenten. Können die Aktivitäten gleichzeitig stattfinden, spricht man von einem parallel ablaufenden (nebenläufigen) System. Ist das System aus räumlich verteilten Komponenten aufgebaut, spricht man von einem verteilten System. Programme, wie wir sie bisher geschrieben haben, arbeiten sequentiell. Beispiel: Banktransaktion single-threaded 4 Der Stand eines Konto wird abgefragt, eine Summe deposit eingezahlt, die Kontostandartvariable um einen Betrag deposit erhöht und der neue Wert als neuer Kontostand angetragen: a = A.getBalance(); a = a + deposit; A.balance = a; // erfragte Kontostand a von Konte A // erhöhe a // setze Kontostand auf neuen Wert von a Bemerkung: Auch reale Bankautomaten und Computerprogramme laufen in solchen Sequenzen ab, die man Thread (Kontrollfluß) nennt. Das obige Prigramm ist ein single-threaded Programm.

Beispiel: Banktransaktion single-threaded In einer realen Bank können Kontoeinzahlungen parallel laufen: 5 a = A.getBalance(); b = B.getBalance(); a = a + deposit; b = b + deposit; A.balance = a; B.balance = b; Bemerkung: Innerhalb eines Computers wird dies multi-threading genannt. Ein Thread kann eine Aufgabe unabhängig von anderen Threads erfüllen. Ebenso wie zwei Bankautomaten die gleichen Konten benutzen können, können Threads Objekte gemeinsam benutzen. Thread 6 Ein Thread ist ein Teil eines Programms, das unabhängig von von anderen Teilen des Programms ausgeführt werden kann, Es repräsentiert eine einzige Sequenz von Anweisungen, d.h. einen sequentiellen Kontrollfluss, der nebenläufig zu anderen Threads ausgeführt werden kann, und der Daten gemeinsam mit anderen Threads benutzt. Aus Betriebssystemsicht wird ein Prozess verstanden als eine abstrakte Maschine, die eine Berechnung ausführt. Da ein Thread im Allgemeinen zusammen mit anderen Threads auf der gleichen abstrakten Maschine läuft und Ressourcen mit anderen Threads teilt, ist ein Thread ein leichtgewichtiger Prozess. Ein nebenläufiges Java-Programm besteht aus mehreren Threads, die über gemeinsame Objekte miteinander kommunizieren.

Sequentielles Speichermodell von Java 7 aktuell auszuführendes Codeteil von main Kontrolle x y o1 o2 Stack Halde Hier entspricht die Ausführung von main einem (single-)thread. Speichermodell für nebenläufige Programme 8 Ein Thread ist ein leichtgewichtiger Prozeß, der die Halde mit anderen Threads gemeinsam benutzt: Thread 1 Kontrolle 1 x1 y1 Thread 2 Kontrolle 2 x2 y2 Stack2 Thread 3 Stack1 Kontrolle 3 x3 y3 o1 o2 Halde Stack3

Variablen in nebenläufigen Prozessen 9 Lokale Variable: Lokale Variablen sind lokal für jeden Thread; Änderungen lokaler Variablen haben keinen Einfluß auf andere Threads. Instanzvariable: Objekte residieren in einem globalen Speicher. Änderungen von Instanzvariablen können die Werte anderer Threads beeinflussen. Scheduling 10 Wenn ein Programm mehrere Threads enthält, wird ihre Ausführung durch das Java-Laufzeitsystem geregelt. Der Scheduler unter Windows NT implementiert eine Zeitschrittstrategie, bei der jeder Thread eine gewisse Prozessorzeit zugeteilt bekommt und dann unterbrochen und in einer Warteschlange hintenangestellt wird. Ältere Implementierungen haben ein solches Verfahren nicht. Ein arbeitender Thread wird nicht unterbrochen und behält den Prozessor, bis er terminiert oder sich selbst in einen Wartezustand bringt. Die Strategien der Implementierungen können also verschieden sein. Deshalb darf man sich im Programm nicht auf ein bestimmtes Verfahren verlassen.

Zustände eines Threads 11 rechnend: blockiert: bereit: terminiert: Der Thread wird im Prozessor ausgeführt. Der Thread braucht ein Betriebsmittel, das temporär nicht vorhanden ist Der Thread ist rechenbereit, hat aber nicht Zugriff auf den Prozessor. Der Thread ist beendet. rechnend terminiert blockiert bereit Das verfeinerte Nebenläufigkeitsmodell 12 In Wirklichkeit besitzt jeder Thread auch eine lokale Halde. Nach genau festgelegten Regeln werden Daten zwischen der lokalen Kontrolle und der lokalen Halde sowie zwischen der lokalen und der globalen Halde ausgetauscht (Forderung nach schwacher Konsistenz.)

Das verfeinerte Nebenläufigkeitsmodell 13 Thread 1 Kontrolle 1 Thread 2 Stack2 Kontrolle 2 x2 y2 Stack1 Halde1 x1 y1... o1 Halde2 o2 o1 o2 Thread 3 Kontrolle 3 Stack3 x3 y3 Halde Halde3 o1 Threads in Java 14 Ein Thread in Java wird repräsentiert durch eine Instanz der Klasse Thread (oder einer Subklasse von Thread) Ein nebenläufiges Java-Programm besteht aus mehreren Threads, die über gemeinsame Objekte miteinander kommunizieren.

Die Klasse java.lang.thread 15 Konstruktoren: Thread () //erzeugt einen neuen Thread Thread (Runnable r) //erzeugt einen neuen Thread, der die //run-methode von r ausführt Methoden: run () // determines the flow of control start () // startet einen Thread und ruft run auf static sleep(long s) // unterbricht den gerade ausgeführten Thread um s msec static yield ()... Erzeugung von Threads 16 2 Techniken: als Objekt der Klasse Thread oder einer (Sub-) Klasse davon durch Implementierung der Schnittstelle Runnable

Erzeugen von Threads in Erben von Thread 17 ruft run auf Schema: class C extends Tread {... public void run {<<bestimmt den Kontrollfluß des Thread>> public static void main (String[] args) { C t = new C(); t.start();... Beispiel: PingPong 18 public class PingPong extends Thread { private String word; // das zu druckende Wort private int delay; // der Unterbrechungszeitraum public PingPong(String whattosay, int delaytime) { word = whattosay; delay = delaytime; public void run() { try { for (;;) // unendliche Schleife { System.out.println(word + " "); sleep(delay); //auf das n"achste Mal warten catch(interruptedexception e) { return ; // beende diesen Thread

Beispiel: PingPong stoppt für 30 ms 19 public static void main(string[] args) { new PingPong("ping", 33).start(); // 1/30 sec. new PingPong("PONG",100).start(); // 1/10 sec. stoppt für 100 ms Bemerkung: Die run-methode von Ping-Pong terminiert nicht und muß deshalb explizit abgebrochen werden mit der InterruptedException von sleep Mögliche Ausgabe ping PONG ping ping PONG ping ping ping PONG... Erzeugen von Threads mit Runnable 20 Eine Subklasse von Thread kann nur von Thread (oder einer Subklasse davon) erben. Mit Hilfe der Schnittstelle Runnable kann ein Thread auch von anderen Klassen erben: public interface Runnable { void run(); Mit den Konstruktoren (der Klasse Thread) public Thread (Runnable r) public Thread (Runnable r, String name) konstruiert man einen neuen Thread, der die run-methode von r verwendet, name gibt einen Namen für den Thread an.

Schematisches Aufbau eines Runnable Threads 21 Schema: class ConcreteRunnable implements Runnable {... public void run() { //Code für den Kontrollfluß public static void main (...) { Runnable r = new ConcreteRunnable(...); //neues Runnable-Objekt Thread t = new Thread (r); // neues Thread-Objekt t.start(); // Aufruf von r.run(); oder ConcreteRunnable Beispiel: PingPong 22 public class RunPingPong extends Thread { << wie vorher >> public static void main(string[] args) { Runnable ping = new RunPingPong("ping", 33); RunPingPong pong = new RunPingPong("PONG",100); new Thread(ping).start(); new Thread(pong).start(); Bemerkung: Die Klasse Thread und damit auch die Erbenklasse RunPingPong implementieren die Schnittstelle Runnable. Deshalb ist das main- Programm (syntaktisch) korrekt.

23 Probleme bei nebenläufiger Programmierung Beispiel: Das folgende (unschöne) Programm für deposit spiegelt das Verhalten eines Bankangestellten wider: void strangedeposit(double d) { double hilf = getbalance(); hilf = hilf + d; balance = hilf; 24 Probleme bei nebenläufiger Programmierung Wenn zwei Kunden gleichzeitig auf das gleiche Konto einzahlen wollen, kann der Kontostand von der Reihenfolge der Einzahlung abhängen: a1 = A.getBalance(); a1 = a1 + deposit; A.balance = a1; a2 = A.getBalance(); a2 = a2 + deposit; A.balance = a2; Jeder Bankangestellte geht zum Kontobuch, sieht den Wert nach und geht dann später wieder hin, um den neuen Wert einzutragen. Damit ist der erste Eintrag verloren. Race Condition, Interferenz zwischen Threads

25 Race Conditions Jeder Bankangestellte geht zum Kontobuch, sieht den Wert nach und geht dann später wieder hin, um den neuen Wert einzutragen. Damit ist der erste Eintrag verloren. Man erhält eine Race Condition, d.h. eine Interferenz zwischen Threads Um Race Conditions zu vermeiden, hat man früher eine Bemerkung auf das Konto A geschrieben: Ich arbeite an dem Konto. In Java setzt man dafür eine Sperre ( Lock ) auf ein Objekt. Eine derartige Sperre ist mit dem Objekt assoziiert, um bestimmen zu können, ob es benutzt ist. 26 Sicherheit durch Synchronisation Interaktion zwischen Threads kann zu unerwünschtem Verhalten führen. Man unterscheidet zwei Arten von Eigenschaften nebenläufiger Programme: Sicherheit: Eigenschaft, daß nie etwas Unerwünschtes geschieht Lebendigkeit: Eigenschaft, dass immer irgendetwas geschieht Sicherheitsfehler führen zu unerwünschtem Laufzeitverhalten Lebendigkeitsprobleme führen dazu, daß das Programm anhält, obwohl noch nicht alle Threads terminiert haben.

Sicherheit und Nebenläufigkeit 27 Sicherheitsprobleme basieren häufig auf Lese / Schreibkonflikten Der Zugriff eines lesenden Kunden auf ein Objekt während eines noch nicht beendeten Schreibvorgangs kann zum lesen inkorrekter Daten führen Beispiel: Lesen einer Reihung während alle Feldelemente verdoppelt werden Schreib/Schreibkonflikte Inkonsistente Zuweisung an Variablen durch nebenläufiges Ausführen von zustandsändernden Methoden (siehe Bankangestellten-Beispiel) Beispiel: Schreib/Schreib-Konflikt (ohne Synchronisation) 28 Thread 1 Thread 2 count = 4 max = 5 If (count < max) count = count + 1 count = 5 count = 6

Beispiel: Schreib/Schreib-Konflikt (ohne Synchronisation) - Ablauf 29 Die lokalen Variablen haben die Werte: count = 4, count = 5 Thread 1 führt den ersten Teil der Anweisung aus if (4 < 5) (also count = max) Threads 2 führt den ersten Teil der Anweisung aus if (4 < 5) (also count = max) Thread 1 führt den 2. Teil der Anweisung aus Ergebnis: 5 = 4 + 1 (count ++) Thread 2 führt den 2. Teil der Anweisung aus Ergebnis: 6 = 5 + 1 (count++) Synchronisation von Methoden 30 Vermeidung von Race Conditions durch Synchronisation: synchronized T m(t Nicht synchronisierte 1 x) Methoden können auf gesperrte Objekte zugreifen Wenn ein Thread o.m(a) aufruft, wird eine Sperre auf o gesetzt. Jeder andere Thread, das o mit einer synchronized-methode aufruft, wird blockiert, bis die Sperre (nach Beendigung der Ausführung von o.m(a)) aufgehoben wird. Durch Synchronisation erreicht man folgende Sicherheitseigenschaft: Es können niemals zwei Threads gleichzeitig auf einem gemeinsamen Datenbereich zugreifen.

Beispiel: Wirkung der Synchronisation Thread 1 o.m()... Thread 2 o.n() wartet, bis er die Sperre für o erhält 31 Bemerkungen 32 Wechselseitiger Ausschluß: Man spricht von wechselseitigem Ausschluß, wenn zu jedem Zeitpunkt nie mehr als ein Prozess auf ein Objekt zugreifen kann. Statische Methoden können auch synchronisiert werden Wird eine synchronisierte Methode in einem Erben überschrieben, so kann sie, muß aber nicht synchronisiert sein.

Beispiel: BankAccount 33 Die folgende Account-Klasse synchronisiert die deposit-operation und garantiert so, dass während der Ausführung von deposit keine andere synchronisierte Operation auf das aktuelle Konto zugreifen kann. public class Account {... public synchronized double getbalance() {... public synchronized void deposit1(double d) { int hilf = getbalance(); hilf = hilf + d; balance = hilf; Zusammenfassung 34 Java unterstützt Nebenläufigkeit durch leichtgewichtige Prozesse, sogenannte Threads, die über die gemeinsame Halde und damit über gemeinsam benutzte Objekte miteinander kommunizieren. Nebenläufigkeit wirft Sicherheits- und Lebendigkeitsprobleme auf. Gemeinsam benutzte Objekte müssen synchronisiert werden.