Muster nebenläufiger Programmierung. concurrent Packet von Java. Alois Schü;e AOSD 1

Ähnliche Dokumente
Synchronisation in Java. Invisible Web

Das Monitorkonzept Brinch-Hansen

Algorithmen und Programmierung IV: Nichtsequentielle Programmierung. Robert Tolksdorf. Freie Universität Berlin

Vorlesung 7. Multithreading in Java 5: Die neuen Concurrency APIs

Verteilte Systeme CS5001

Multithreading ab Java 5: Die neuen Concurrency APIs

5. Threads, Serverprozesse und Benachrichtigungen

Algorithmen und Datenstrukturen II

Mobile und Verteilte Datenbanken

2.2 Prozesse in Java

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

Synchronisation von Variablen und Operationen (gemeinsamer Speicher)

Musterlösungen zur Klausur Informatik 3

Nebenläufige Anwendungen in Java (J2SE, Rich Client, J2EE)

Mobile und Verteilte Datenbanken

Java-Schulung Grundlagen

Nebenläufige und verteilte Programme CS2301

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

Einführung in die Programmierung Blockkurs Java

Monitore. Klicken bearbeiten


Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 14/15. Kapitel 11. Fehler und Ausnahmen 1

Java-Programmierung. Remote Method Invocation - RMI

Grundlagen zur nebenläufigen Programmierung in Java

Variablen manipulieren per JDI

Nebenläufige Programmierung I

Java Real-Time Specification

1 Polymorphie (Vielgestaltigkeit)

Nebenläufige Programmierung in Java

LeJOS: Mindstorms in Java programmieren

AK-Automatisierungs und Kommunikationstechnik TI Technische Informatik. NWT Netzwerktechnik

Parallele Programmierung in Java

Programmieren in Java

1. Der Einstieg in Java. Was heißt Programmieren?

// Zeigt den insgesamt einbezahlten Betrag auf der Bank. // Muss 1600 GE sein. System.out.println("Current Bank balance: " + b.

Grundlagen der Informatik Ausnahmebehandlung & Threads

Java - Programmierung - Objektorientierte Programmierung 1

2A Basistechniken: Weitere Aufgaben

Java: Vererbung. Teil 3: super()

VS4 Slide 1. Verteilte Systeme. Vorlesung 4 vom Dr. Sebastian Iwanowski FH Wedel

Algorithmen und Datenstrukturen

Übersicht. Informatik 2 Teil 3 Anwendungsbeispiel für objektorientierte Programmierung

Multi-Threading. Ralf Abramowitsch Vector Informatik GmbH

Übung zu Grundlagen der Betriebssysteme. 9. Übung

Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden.

Schritt 1 - Ein Spielfeld

3 Objektorientierte Konzepte in Java

Datenbankanwendungsprogrammierung Crashkurs Java

Problemstellung. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 24: Reflection 1. IDE und automatische Tests.

3 Objektorientierte Konzepte in Java

Distributed Computing Group

CS2101 Nebenläufige und Verteilte Programme Bachelor of Science (Informatik)

Allgemein: Klassen testbar machen. 5. Mocking. Mocks programmieren. Zusammenspiel von Klassen testen

Übung 1 mit C# 6.0 MATTHIAS RONCORONI

Java Game Development Fabian Birzele Programmierpraktikum 2008 / 2009

#define N 5 // Anzahl der Philosophen. while (TRUE) { // Der Philosoph denkt

Beispiel: Methode mit einem Fehler. Diese Methode wird problematisch, wenn von außen eine Dauer von 0 Sekunden angegeben wird, etwa im Aufruf

Objektorientierte Programmierung

Innere Klassen in Java

Rekursion. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Testen mit JUnit. Martin Wirsing. Ziele. in Zusammenarbeit mit Michael Barth, Philipp Meier und Gefei Zhang

Java für Computerlinguisten

Primitive Datentypen

Anleitung. Ein einfaches RMI-Beispiel. (ab Java 5.0) c Y. Pfeifer. (Juni 2014)

Große Übung Praktische Informatik 1

Infrastruktur und Betriebssysteme III. Martin Plümicke

Verteilte Systeme CS5001

1. Der Einstieg in Java

Linux Prinzipien und Programmierung

Beispiel: DB-Mock (1/7)

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck

Sichtbarkeit & statische Methoden. Einsatz von Sichtbarkeit Einsatz statischer Methoden programmatische Realisierung 2 Beispielaufgaben

Programmieren in Java

Programmierkurs Java

Universität Karlsruhe (TH)

i n g e n i e u r b ü r o f ü r s o f t w a r e t e c h n o l o g i e w w w. v o e l t e r. d e Servlet Debugging

5. Tutorium zu Programmieren

Themen. Web Service - Clients. Kommunikation zw. Web Services

Info: Standard DO-178B. 5. Mocking. Zusammenspiel von Klassen testen. Allgemein: Klassen testbar machen

Lösungsvorschläge. zu den Aufgaben im Kapitel 4

Kapitel 6. Vererbung

Einführung in Javadoc

Kapitel 6. Vererbung

Teilprüfung Software- und Internettechnologie Programmierkurs 1 Wintersemester 2005/2006

am Beispiel von JUnit

7. Performance und Speicherauslastung

Applet Firewall und Freigabe der Objekte

Software-Engineering Software-Management

Remote Method Invocation

Assoziation und Aggregation

Objektorientierte Programmierung

Lösung zu Praktikum 1 -Programmierung eines Java Card Applets-

TCP/IP Programmierung. C# TimeServer Java6 TimeClient

Praktikum Informatik II Prof. Dr. Martin Trauth, Dr. Michael Männel

Angewandte IT-Sicherheit

4. Thread- und Netzwerk- Programmierung

Universität Augsburg, Institut für Informatik Sommersemester 2003 Prof. Dr. Bernhard Bauer 18. Oktober 2003 Stefan Fischer, Dr.

Kapitel 6. Vererbung

U08 Entwurfsmuster (II)

Transkript:

Muster nebenläufiger Programmierung concurrent Packet von Java Alois Schü;e AOSD 1

Concurrent Packet In diesem Teil der Veranstaltung werde Muster nebenläufiger Programmierung diskueert. Dazu wird das concurrent Packet von Java betrachtet. Alois Schü;e AOSD 2

Concurrent Packet - Überblick Standard- Mi;el von Java bezogen auf Nebenläufigkeit sind: Threads mit dem Interface Runnable SynchronisaEons- Mechanismen synchronized, wait, notify und notifyall. Ab Java 5 sind im Paket java.util.concurrent Klassen für Standard- Muster der parallelen Programmierung enthalten, z.b.: Locks Queues Thread- Pooling Scheduling Semaphore Exchanger CountDownLatch CyclicBarrier Alois Schü;e AOSD 3

Concurrent Packet - Locks Lockkonzept Ein Lock ist ein Mi;el, um in mul$threading Umgebungen den gemeinsamen Zugriff auf Ressourcen zu koordinieren. Um eine Ressource nutzen zu können, muss ein Thread den zugehörigen Schlüssel anfordern. Solange ein Thread den Schlüssel besitzt, kann kein anderer Thread die Ressource verwenden, er muss warten. Der den Schlüssel besitzende Thread gibt ihn frei, darau\in kann ein wartender Thread den Schlüssel bekommen und die Ressource verwenden. Dieses Lockkonzept könnte mit synchronized umgesetzt werden. Dabei hat man aber immer die Blockstruktur als Einschränkung. java.util.concurrent.locks beinhaltet Interfaces und Klassen für Locks. Alois Schü;e AOSD 4

Concurrent Packet - Locks Die Klasse TimeUnit wird im Zusammenhang mit Locks verwendet, um eine Zeitdauer in SECONDS, MICROSECONDS, MILLISECONDS oder NANOSECONDS angeben zu können. $ cat TimeUnit/MainClass.java import static java.util.concurrent.timeunit.*; public class MainClass extends Thread { // This field is volatile because two different threads may access it volatile boolean keeprunning = true; public void run() { while (keeprunning) { long now = System.currentTimeMillis(); System.out.printf("%tr%n", now); try { Thread.sleep(1000); // millisecs catch (InterruptedException e) { return; // run In der run- Methode wird die Methode sleep von Thread verwendet. Es wird eine Sekunde geschlafen. Alois Schü;e AOSD 5

Concurrent Packet - Locks $ public void pleasestop() { keeprunning = false; public static void main(string[] args) { MainClass thread = new MainClass(); thread.start(); try { SECONDS.sleep(10); // = MILLISECONDS.sleep(10000) catch (InterruptedException ignore) { thread.pleasestop(); // main Innerhalb main wird SECONDS von TimeUnit verwendet, um das Programm 10 Sekunden lang laufen zu lassen. $ java MainClass 10:19:51 AM 10:19:52 AM 10:19:53 AM 10:19:54 AM 10:19:55 AM 10:19:56 AM 10:19:57 AM 10:19:58 AM 10:19:59 AM 10:20:00 AM $ Alois Schü;e AOSD 6

Concurrent Packet - Locks Das Interface Lock spezifiziert das Verhalten von Lock- Objekten. public interface Lock { void lock(); void lockinterruptible() throws InterruptedException; boolean trylock(); boolean trylock(long time, TimeUnit unit) throws InterruptedException void unlock(); Condition newcondition(); // Erklärung später lock wartet, bis der Objektschlüssel verfügbar ist und belegt ihn dann. unlock gibt das Objekt frei. lockinterruptible funkeoniert wie lock, aber es wird eine Ausnahme geworfen, wenn ein anderer Thread den Thread durch interrupt unterbricht. trylock liefert false, wenn das Objekt nicht verfügbar ist; ansonsten wird das Objekt in Besitz genommen und true returniert. trylock(long, TimeUnit) funkeoniert wie trylock, aber es wird eine maximale Zeitspanne gewartet, wenn das Objekt nicht verfügbar ist. Alois Schü;e AOSD 7

Concurrent Packet Locks - ReentrantLock Die Klasse ReentrantLock implemeneert die Schni;stelle Lock. public class ReentrantLock implements Lock, Serializable { public ReentrantLock(boolean fair); public ReentrantLock; // Methods of Lock void lock(); void lockinterruptible() throws InterruptedException; boolean trylock(); boolean trylock(long time, TimeUnit unit) throws InterruptedException void unlock(); Condition newcondition(); // additional Methods public boolean isfair(); public int getholdcount(); public int getqueuelength(); public boolean isheldbycurrentthread(); public boolean islocked(); protected Thread getowner(); protected Collection<Thread> getqueuedthreda(); Alois Schü;e AOSD 8

Concurrent Packet Locks - ReentrantLock Der Konstruktor kann die Angabe eine fair- Paramerters haben. Wenn mehrere Threads auf den Lock warten, garaneert fair==true, dass der am längsten wartende Thread das Lock- Objekt erhält. isfair liefert den fair- Parameter des Konstruktors zurück. Ein Lock enthält eine Zähler, der bei jedem lock inkremeneert, bei unlock dekremeneert wird. Ein Thread kann also öier lock aufrufen. getholdcount liefert den Wert des Zählers. getqueuelength returniert die Anzahl der auf einen Lock wartenden Threads. isheldbycurrentthread ist true, wenn der aufrufende Thread den Lock hält. islocked ist true, wenn irgendein Thread den Lock hält. getowner(), CollecEon<Thread> getqueuedthreads liefern den Besitzer und die wartenden Threads. Alois Schü;e AOSD 9

Concurrent Packet Locks - ReentrantLock Beispiel: Klasse Konto (Account), Geldabholer (Withdrawer als Thread) Zunächst die Realisierung der Klasse Account mit synchronized. $ cat ReentrantLock/synchronized/WithdrawApp.java class Account { private float balance; public Account (float initialbalance) { balance = initialbalance; public synchronized float getbalance() { return balance; // getbalance public synchronized void withdraw( float amount) { if (amount < 0 balance < amount) throw new IllegalArgumentException("withdraw: wrong amount " + amount); try { Thread.sleep(1000); catch (Exception e) {; balance -= amount; // withdraw // Account synchronized ist erforderlich, da ein Konto von mehreren Threads verwendet werden kann und mindestens einer den Zustand per withdraw ändern kann. Alois Schü;e AOSD 10

Concurrent Packet Locks - ReentrantLock Nun die Realisierung der Klasse Account mi;els Locks. Die Blockstruktur von synchronized muss mi;els lock und unlock nachgebildet werden: import java.util.concurrent.locks.*; private final ReentrantLock lock = new ReentrantLock(true); lock.lock(); try {... finally { lock.unlock(); WichEg: Da im try- Block Ausnahmen auireten können ist mi;els finally sicherzustellen, dass stets unlock aufgerufen wird! Nur so werden gelockte Objekte immer freigegeben. Die Verwendung von lock- unlock ist also aufwendiger, dafür aber universell: ein Thread kann lock aufrufen, ein andere unlock Soll anstelle einer Objektsperre eine Klassensperre deklariert werden, wird die Lock- Variable als sta$c definiert. Alois Schü;e AOSD 11

Concurrent Packet Locks - ReentrantLock $ cat ReentrantLock/ReentrantLock/WithdrawApp.java import java.util.concurrent.locks.*; class Account { private float balance; private final ReentrantLock lock = new ReentrantLock(true); public Account (float initialbalance) { balance = initialbalance; // Account public float getbalance() { lock.lock(); try { return balance; finally {lock.unlock(); // getbalance public void withdraw( float amount) { lock.lock(); try { if (amount < 0 balance < amount) throw new IllegalArgumentException("withdraw: wrong amount " + amount); try { Thread.sleep(1000); catch (Exception e) {; balance -= amount; finally {lock.unlock(); // withdraw // Account Alois Schü;e AOSD 12

Concurrent Packet Locks - ReentrantLock Was muss geändert werden, wenn Jenni und Hannah nicht gleichzeieg Geld abholen dürfen? Idee: Der erste Abholer hält den Lock, der zweite muss abgewiesen werden. Lösung: trylock anstelle von lock $ cat ReentrantLock/tryLock/WithdrawApp.java public void withdraw( float amount ) { if (lock.trylock() == false) return; try { if (amount < 0 balance < amount) throw new IllegalArgumentException("withdraw:...); try { Thread.sleep(1000); catch (Exception e) {; balance -= amount; finally { lock.unlock(); // withdraw Alois Schü;e AOSD 13

Concurrent Packet Locks - CondiEon Die Methode newcondi$on des Interface Lock liefert ein CondiEon- Objekt zurück. Genauer, ein Objekt einer Klasse die die Schni;stelle CondiEon implemeneert. public interface Condition { void await() throm InterruptedException; void awaituninterruptibly(); boolean await(long time Timeunit unit) throm InterruptedException; long awaitnanos(long time) throm InterruptedException; boolean awaituntil(date deadline) throm InterruptedException; void signal(); void signalall(); Die Methoden haben Ähnlichkeit zu wait und noefy. Eine CondiEon ist signalisiert oder nicht signalisiert. Sofort nach ihrer Erzeugung ist sie signalisiert. Ein await- Aufruf ( wait) auf einer signalisierten CondiEon kehrt sofort zurück. Vor Rückkehr von await wird die CondiEon in den nicht signalisierten Zustand versetzt. signal ( noefy) versetzt eine CondiEon in den signalisierten Zustand, weckt also einen wartenden Thread signalall ( noefyall) weckt alle auf die CondiEon wartenden Threads. Alois Schü;e AOSD 14

Concurrent Packet Locks - CondiEon Beispiel: BoundedBuffer, zunächst mit synchronized. $ cat Condition/BoundedBuffer/synchronized/BoundedBufferApp.java class BoundedBuffer { private float[] buffer; private int first, last; private int numberinbuffer = 0, size; BoundedBuffer(int length) { size = length; buffer = new float[size]; first = last = 0; public synchronized void dumpbuffer() { System.err.print("Buffer: "); // use err channel to log for (int i=(first+1)%size, j=0; j<numberinbuffer; j++, i=(i+1)%size) System.err.print(buffer[i] + " "); System.err.println(" "); float Puffer fester Grösse dumpbuffer zum Debuggen des Puffers über stderr Alois Schü;e AOSD 15

Concurrent Packet Locks - CondiEon Beispiel: BoundedBuffer, zunächst mit synchronized. $ cat Condition/BoundedBuffer/synchronized/BoundedBufferApp.java class BoundedBuffer { private float[] buffer; private int first, last; private int numberinbuffer = 0, size; BoundedBuffer(int length) { size = length; buffer = new float[size]; first = last = 0; public synchronized void dumpbuffer() { System.err.print("Buffer: "); // use err channel to log for (int i=(first+1)%size, j=0; j<numberinbuffer; j++, i=(i+1)%size) System.err.print(buffer[i] + " "); System.err.println(" "); float Puffer fester Grösse dumpbuffer zum Debuggen des Puffers über stderr Alois Schü;e AOSD 16

Concurrent Packet Locks - CondiEon Beispiel: BoundedBuffer, zunächst mit synchronized. public synchronized void put(float item) throws InterruptedException { while(numberinbuffer == size) wait(); last = (last+1)%size; numberinbuffer++; buffer[last] = item; dumpbuffer(); notifyall(); public synchronized float get() throws InterruptedException { while(numberinbuffer == 0) wait(); first = (first+1)%size; numberinbuffer--; dumpbuffer(); notifyall(); return buffer[first]; // BoundedBuffer Die Methoden put und get sind mi;els synchronized synchronisiert. last ist Einfügestelle. von first wird gelesen. Alois Schü;e AOSD 17

Der Produzent verwendet die put- Methode: Concurrent Packet Locks - CondiEon class Producer extends Thread { private BoundedBuffer buffer; public Producer(BoundedBuffer b) { buffer = b; public void run() { for(int i = 0; i < 100; i++) { try { buffer.put(i); System.out.println("put " + i); catch (InterruptedException ingnored) {; // Producer Alois Schü;e AOSD 18

Concurrent Packet Locks - CondiEon Wie kann man dies nun mi;els CondiEon realisieren und wo sind die Vorteile? $ cat Condition/BoundedBuffer/condition/BoundedBufferApp.java class BoundedBuffer { private float[] buffer; private int first, last; private int numberinbuffer = 0, size; private ReentrantLock lock = new ReentrantLock(); private final Condition notfull = lock.newcondition(); private final Condition notempty = lock.newcondition(); BoundedBuffer(int length) {... public void dumpbuffer() {... lock ist ein ReentrantLock Objekt. Es gibt zwei Condi$on AKribute, notfull und notempty für das Objekt lock. Alois Schü;e AOSD 19

Concurrent Packet Locks - CondiEon put: public void put(float item) throws InterruptedException { lock.lock(); try { while(numberinbuffer == size) notfull.await(); last = (last+1)%size; numberinbuffer++; buffer[last] = item; dumpbuffer(); notempty.signal(); finally { lock.unlock(); Wenn der Buffer voll ist, wird gewartet, bis eine Condi$on notfull signalisiert wird. Nach dem Schreiben in den Buffer wird signaliert notempty. Alois Schü;e AOSD 20

Concurrent Packet Locks - CondiEon get: public float get() throws InterruptedException { lock.lock(); try { while(numberinbuffer == 0) notempty.await(); first = (first+1)%size; numberinbuffer--; dumpbuffer(); notfull.signal(); return buffer[first]; finally { lock.unlock(); Wenn der Buffer leer ist, wird gewartet, bis eine Condi$on notempty signalisiert wird. Nach dem Lesen des Buffer wird signaliert notfull. Insgesamt ist man also mit Locks und CondiEons flexibler, man kann unterschiedliche Bedingungen signalisieren und so gezielt nur bes$mmte Threads wecken (eben die die auf die CondiEon warten). Alois Schü;e AOSD 21