Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

1 Wiederholung: Threads Threads können „parallel“ ablaufen In Java sorgt die JVM für die Zuteilung von Rechenzeit an die Threads. Beispiele für Anwendung:

Ähnliche Präsentationen


Präsentation zum Thema: "1 Wiederholung: Threads Threads können „parallel“ ablaufen In Java sorgt die JVM für die Zuteilung von Rechenzeit an die Threads. Beispiele für Anwendung:"—  Präsentation transkript:

1 1 Wiederholung: Threads Threads können „parallel“ ablaufen In Java sorgt die JVM für die Zuteilung von Rechenzeit an die Threads. Beispiele für Anwendung: Webserver verarbeitet parallel eingehende Anfragen Laufschrift in einer Bildschirmmaske

2 2 Geschwindigkeitssteigerung durch Threads? Beispiel: Heap-Sort Das Herstellen der Heap-Bedingung in verschiedenen Unterbäumen kann in verschiedenen Threads erfolgen. Auf einem Multiprozessorsystem (und nur dort) führt das zu einer Geschwindigkeitssteigerung (Sind allerdings zum Zugriff auf das zu sortierende Feld Dateizugriffe erforderlich, kann das den Nutzen der parallele Arbeitsweise wieder zunichte machen.) Auf einem Einzelprozessorsystem ist eine Geschwindigkeitssteigerung durch parallele Threads nur zu erreichen, wenn beispielsweise: Thread A intensiv rechnet während Thread B intensiv die Festplatte nutzt oder Thread C intensiv vom Netzwerk liest

3 3 Wiederholung: Threads in Java class XYZ extends Thread { public void run() {... } } class Hauptprogramm { Thread a = new XYZ(); a.start() } Alternative zum Erben von Thread: Implementieren des Interfaces Runnable

4 4 Mögliche Probleme bei Parallelität public class Konto { private int Kontostand;... public void zahleEin(int betrag) { Kontostand = Kontostand - betrag } public void hebeAb(int betrag) { Kontostand = Kontostand - betrag }

5 5 Möglicher Ablauf Kontostand anfangs = 1234,00 Thread A (500,00 einzahlen) Kontostand lesen: 1234,00 500,00 addieren Kontostand schreiben: 1734,00 Thread B (100,00 abheben) Kontostand lesen: 1734,00 100,00 subtrahieren Kontostand schreiben: 1634,00

6 6 Oder auch so... Kontostand anfangs = 1234,00 Thread A (500,00 einzahlen) Kontostand lesen: 1234,00 500,00 addieren Kontostand schreiben: 1734,00 Thread B (100,00 abheben) Kontostand lesen: 1234,00 100,00 subtrahieren Kontostand schreiben: 1134,00 

7 7 Zuteilung von Rechenzeit an die Threads Wie im Beispiel gesehen: Ohne besondere Vorkehrungen ist nicht vorhersehbar, zu welchem Zeitpunkt welcher Thread gerade welche Operation ausführt. Folge: Programme mit Threads sind oft schwerer zu testen.

8 8 Kritische Abschnitte / Monitore Ein kritischer Abschnitt ist eine Ressource, auf den immer nur ein Prozess zugreifen darf. Eine typische Art von kritischen Abschnitten sind Variablen, diese dürfen nicht beliebig parallel gelesen und geschrieben werden. Sperren sind ein Mittel, um den parallelen Zugriff auf Ressourcen zu reglementieren. Es ist möglich, kritische Abschnitte zu schützen, so dass nur ein Thread zu einem Zeitpunkt darauf zugreifen darf. Dies geschieht mithilfe so genannter Monitore (Locks).

9 9 Synchronisierter Ablauf Kontostand anfangs = 1234,00 Thread A (500,00 einzahlen) Belegt den Monitor auf das zu ändernde Konto-Objekt Kontostand lesen: 1234,00 500,00 addieren Kontostand schreiben: 1734,00 Gibt den Monitor auf das geänderte Konto-Objekt wieder frei Thread B (100,00 abheben) Darf nicht zugreifen, da sich Thread A das Objekt per Monitor „reserviert“ hat  Thread B reiht sich in Warteliste ein Kontostand lesen: 1734,00 100,00 subtrahieren Kontostand schreiben: 1634,00

10 10 Synchronisation In Java: Schlüsselwort synchronized (Ab Java 5: Alternative java.util.concurrent.locks.Lock, hier nicht behandelt) Für ein Objekt als synchronized definierte Methoden (oder Blöcke) darf immer nur ein Thread zugleich ausführen. Die anderen Threads kommen in eine Warteschlange, in der alle Threads verwaltet werden, die die synchronized Methode ausführen wollen. Threads kommen in diese Warteschlange, wenn: sie eine synchronized Methode aufrufen, während ein anderer Thread auf das Objekt zugreift, wenn sie in der aufgerufenen, synchronized Methode yield() aufrufen.

11 11 Beispiel für Monitor public class Konto { private int Kontostand;... public synchronized void zahleEin(int betrag) { Kontostand = Kontostand - betrag } public synchronized void hebeAb(int betrag) { Kontostand = Kontostand - betrag }

12 12 Monitorkonzept Es lassen sich sowohl einzelne Blöcke, als auch ganze Methoden schützen: Eine ganze Methode kann durch Kennzeichnung von synchronized geschützt werden, z. B.: public synchronized void zahleEin{... } Ein Block kann durch synchronized( ObjektName ) {... } geschützt werden. Hierbei wird der Monitor des Objektes ObjektName belegt.

13 13 Parallelitätsregeln Wenn zwei oder mehr Threads auf ein Objekt zugreifen...... gibt‘s kein Problem, wenn alle nur lesen. Wenn jedoch ein Thread den Inhalt des Objektes veränert, so sollten alle Methoden, die auf das Objekt zugreifen, als synchronized deklariert werden. Wenn eine Methode auf das Ergebnis eines anderen Threads warten muss, um das Objekt zu ändern, dann sollte wait() aufgerufen werden. Wenn eine synchronized Methode ihr Objekt geändert hat, dann sollten die gerade wartenden Prozesse mit notifyAll() alarmiert werden.

14 14 Methoden der Klasse Object Monitor vorübergehend freigeben: Mit der Methode public final void wait() throws InterruptedException wird der Monitor freigegeben und der Thread geht in einen Wartezustand, bis er von einem anderen Thread durch notify() oder notifyAll() geweckt wird Nach Wecken setzt der Thread seine Arbeit an gleicher Stelle fort Wichtig, um auf nicht freie Resourcen zu warten => andere Threads müssen die Chance bekommen, die Ressourcen freizugeben

15 15 Methoden der Klasse Object Wird für einen Thread wait() aufgerufen, kommt er in die Wartemenge des Objektes (nicht zu verwechseln mit der bereits erwähnten Warteschlange der Threads, die einen Monitor erlangen wollen!) Wir haben also zwei Sorten von „warten“ WAITING: warte auf notify, Thread nimmt nicht an der Vergabe der Rechenzeit teil. BLOCKED: warte darauf, einen Monitor zu bekommen Aufwecken von Threads im Status WAITING Die Methode public final void notify() der Klasse Object benachrichtigt einen Thread aus der Warteliste auf den zum Objekt zugehörigen Monitor (willkürliche Auswahl) Die Methode public final void notifyAll() der Klasse Object benachrichtigt alle Threads aus der Warteliste, diese werden um den Monitor konkurrieren

16 16 Datenaustausch zwischen Threads Wenn Daten zwischen Threads ausgetauscht werden sollen, gibt es Synchronisationsprobleme. Unser Beispiel: zwei parallele Threads: Thread Erzeuger erzeugt Daten Thread Verbraucher verarbeitet (verbraucht) diese Kommunikation zwischen den beiden Threads erfolgt über eine Klasse Tunnel: Sie soll von einem Thread jeweils ein Paket Daten aufnehmen und an den anderen Thread weitergeben. Klar ist: Verbraucher-Thread muss warten, bis Daten im Tunnel vorhanden sind. Der Erzeuger-Thread soll erst dann wieder etwas erzeugen, wenn der Verbraucher-Thread aus dem Tunnel gelesen hat (d.h. Tunnel kann genau einen Wert aufnehmen).

17 17 Handshake-Verfahren: Erzeuger class Erzeuger extends Thread { private Tunnel t; public Erzeuger(Tunnel tunnel) { t = tunnel; } public void run() { for (int i=0; i<5; i++) { t.geben(i); System.out.println("Erzeuger schreibt " + i); try { Thread.sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { }

18 18 Handshake-Verfahren: Verbraucher class Verbraucher extends Thread { private Tunnel t; public Verbraucher(Tunnel tunnel) { t = tunnel; } public void run() { int wert = 0; for (int i=0; i<5; i++) { wert = t.nehmen(); System.out.println("Verbraucher liest " + wert); }

19 19 Handshake-Verfahren: Tunnel class Tunnel { private int inhalt; private boolean DatenVorhanden = false; public synchronized int nehmen() { // Liest int aus Tunnel while (DatenVorhanden == false) { try { wait(); } catch (InterruptedException e){} } DatenVorhanden = false; notifyAll(); return inhalt; } public synchronized void geben(int wert) { // Schreibt int in Tunnel while (DatenVorhanden == true) { try { wait(); } catch (InterruptedException e) {} } inhalt = wert; DatenVorhanden = true; notifyAll(); }

20 20 Handshake-Verfahren: StartKlasse class StartKlasse { public static void main(String[] args) { Tunnel t = new Tunnel(); // Das Objekt mit dem Monitor Erzeuger e = new Erzeuger(t); Verbraucher v = new Verbraucher(t); e.start(); v.start(); } Ausgabe: } Erzeuger schreibt 0 Verbraucher liest 0 Verbraucher liest 1 Erzeuger schreibt 1 Verbraucher liest 2 Erzeuger schreibt 2 Verbraucher liest 3 Erzeuger schreibt 3 Verbraucher liest 4 Erzeuger schreibt 4 Hinweis: nehmen und geben ist synchronisiert, nicht aber die Ausgabe!

21 21 Deadlocks Vorsicht! Mit dem beschriebenen Vorgehen kann man mühelos einen sog. Deadlock (Verklemmung) erzeugen: Es gibt zwei kritische Ressourcen x und y, jede hat einen Monitor. Zwei Threads alpha und beta versuchen beide auf diese Ressourcen zuzugreifen. Jeder dieser Threads kann seine Aufgabe erst dann erfüllen, wenn er die Monitore auf beide Ressourcen erhalten hat. Mögliche Situation: alpha bekommt Monitor auf x beta bekommt Monitor auf y Beide warten nun vergeblich auf den jeweils anderen Monitor.

22 22 VE 12 Java Bibliotheken io und util

23 23 Überblick (Auszug) java.applet Applet-Programmierung java.awt GUI-Programmierung mit AWT java.beans JavaBeans™-Entwicklung java.io Ein-/Ausgabe-Operationen, Datenströme java.lang fundamentale Klassen (z.B. String ) java.net Netzwerkfunktionen java.rmi Remote Method Invocation java.security Zertifikate, Kryptographie java.sql Datenbank-Funktionen java.util Klassen für Datenstrukturen javax.swing GUI-Programmierung mit Swing und viele mehr (XML, CORBA, Namensdienste, Sound...)

24 24 Java API Specification

25 25 Dateien und Streams java.io.*

26 26 Motivation Wofür braucht man Ein- und Ausgaben? Datenaustausch zwischen Mensch und Maschine (trivial ) für die Kommunikation von Maschinen untereinander (z.B. Rechner  Drucker) um Persistenz von Objekten (also Daten) zu ermöglichen

27 27 Persistenz Von Persistenz eines Objektes spricht man: wenn das Objekt das Ende einer Programmausführung überlebt und von einem anderen Programm (oder einer anderen Ausführung des gleichen Programms) benutzt werden kann. Persistent werden Objekte, indem man sie speichert. Speicherort kann das Dateisystem sein oder auch eine Datenbank.

28 28 Persistenz Die Beschreibung der Struktur persistenter Objekte wird das Format genannt. Problem: wie werden Objekte persistent gemacht? Wie lassen sich solche persistent gemachten Objekte wieder einlesen? Wie einigen sich Schreiber und Leser auf Formate? Java-Ansatz: Eine Reihe von Formaten wird in Form von Klassen und Interfaces vordefiniert. Hierzu gehört das eigentliche Format und natürlich auch der schreibende bzw. lesende Zugriff.

29 29 Ganz unten: Dateisystem Computer speichern Daten auf verschiedenen Medien (Festplatten, CD, DVD etc.) in Dateisystemen diese bestehen aus Dateien (enthalten die eigentlichen Daten) und Verzeichnisstruktur (organisiert Dateien und hält Info bereit) Dateien haben Attribute Name, Typ, Ort, Größe etc und es gibt spezifische Methoden neue Dateien erzeugen in Dateien schreiben aus Dateien lesen Dateien löschen...

30 30 Ganz unten: Dateisystem Verzeichnisstruktur organisiert Dateien in einem Verzeichnisbaum und es gibt typische Operationen: Inhalt eines Verzeichnisses anzeigen Unterverzeichnis anlegen Unterverzeichnis löschen Dateien in Verzeichnis auflisten...

31 31 Zugriff auf Dateisystem in Java Natürlich ist eine Datei in Java wieder ein Objekt, und zwar von der Klasse java.io.File Beachte: Dieses Objekt steht für den Speicherort einer Datei, nicht für den Inhalt der Datei. Objekte werden erzeugt, um Dateien erzeugen, öffnen und schließen zu können und für Zugriffe auf das Dateisystem import java.io.File public void erzeugeDatei { File datei = new File("Test.txt"); System.out.println("Dateiname: " + datei.getName()); } Ausgabe: Dateiname: Test.txt

32 32 java.io.File Konstruktor: public File(String pathname) throws NullPointerException Erzeugt Objekt über Pfadnamen Prüfung von Eigenschaften: public boolean exists() public boolean canRead() public boolean canWrite() public boolean isFile() public boolean isDirectory() public boolean isHidden() public long length()

33 33 java.io.File Methoden: public boolean delete() Löscht Datei oder Verzeichnis public void deleteOnExit() Löscht bei Beendigung der Virtual Machine Flag wird gesetzt, welches nicht zurückgenommen werden kann public boolean mkdir() Erstellt Verzeichnis public boolean mkdirs() Erstellt Verzeichnis und eventuell benötigte, nicht existierende Mutterverzeichnisse

34 34 java.io.File public String[] list() liefert Array mit Auflistung aller Einträge in Verzeichnis, das durch Namen des File -Objekts gegeben ist public String[] list(FilenameFilter filter) liefert Array mit Auflistung aller Einträge in Verzeichnis, das durch Namen des File -Objekts gegeben ist diese Auflistung ist jedoch gefiltert, dies wird von filter übernommen filter ist Objekt einer Klasse, die das Interface FilenameFilter implementiert

35 35 Gefilterte Dateiliste Interface FilenameFilter kann von einer Klasse implementiert werden dadurch lässt sich das Ergebnis von File.list() beeinflussen Inhalt des Interfaces FilenameFilter : public interface FilenameFilter { boolean accept(File dir, String name); } Es reicht, die accept() -Methode sinnvoll zu implementieren

36 36 Gefilterte Dateiliste - Beispiel Beispiel: Filter, der nur Dateinamen durchlässt, die eine bestimmte Zeichenkette enthalten public class DirFilter implements FilenameFilter { String afn; DirFilter(String afn) { this.afn = afn; } public boolean accept(File dir, String name) { String f = new File(name).getName(); return f.indexOf(afn) != -1; }

37 37 Gefilterte Dateiliste - Beispiel Verwendung des Filters: File path = new File("."); String[] list; list = path.list(new DirFilter("xyz")); sorgt dafür, dass in list[] nur die Dateinamen aus dem aktuellen Verzeichnis („.“) aufgenommen werden, die „xyz“ enthalten.


Herunterladen ppt "1 Wiederholung: Threads Threads können „parallel“ ablaufen In Java sorgt die JVM für die Zuteilung von Rechenzeit an die Threads. Beispiele für Anwendung:"

Ähnliche Präsentationen


Google-Anzeigen