Nebenläufigkeit in Java

Save this PDF as:
 WORD  PNG  TXT  JPG

Größe: px
Ab Seite anzeigen:

Download "Nebenläufigkeit in Java"

Transkript

1 Nebenläufigkeit in Java Maurice Schoenmakers muenchen.de Inhaltsverzeichnis 1 Einleitung Prozesse und Threads in Java Die Klasse Thread Der aktuelle Thread Mehrere Threads Mehrere Threads mit gemeinsamen Variablen Synchronisation paralleler Threads in Java Kritischer Bereich Bewachte kritische Bereiche Das Monitor Konzept in Java Semaphore Ganzzahlige Semaphore Boolesche Semaphore Verklemmung Koch Beispiel Verschachteltes Monitor Problem Zuteilungsstrategien in Java für Threads Zeitscheibenstrategie Sperre mit Warteschlange Anmerkungen Literatur... 28

2 1 Einleitung Ziel dieser Zusammenfassung ist es, die Programmierkonzepte in Java zur Erzeugung und Synchronisation von Nebenläufigkeit zu erläutern. Einfache Grundkentnisse in Java werden dabei vorausgesetzt. Die erläuterten Programmierkonzepte werden im Bezug gesetzt zu den Grundbegriffen zur Programmierung verteilter Systeme aus dem Kapitel 1 des Buches "Informatik, Eine grundlegende Einführung" [Bro98]. 2 Prozesse und Threads in Java Ein Java Programm besitzt in der Regel eine Klasse mit einer statischen Methode main(). Bei jedem Start eines Java Programms erzeugt das Betriebsystem einen Prozeß und startet die virtuelle Maschine (VM). Die virtuelle Maschine erzeugt einen Haupt Thread (engl.main thread) auch Programmfaden, Kontrollfluß oder leichtgewichtiger Prozeß genannt. Der Haupt Thread führt daraufhin die Methode main() aus. Es wird also zwischen Java Prozesse und Threads (threads) unterschieden. Ein Java Prozeß kann als Realisierung eines Prozesses des Prozeßmodells der Vorlesung gesehen werden. Ein Java Thread entspricht einem sequentiellen Teilprozeß. Alle Teilprozesse zusammen formen den Gesamtprozeß. Eine Methode im Quelltext besteht aus eine Sequenz von Anweisungen. Beim Übersetzen des Quelltextes, wird jede Anweisung in mehrere elementare Teilanweisungen (byte codes) für die VM zerlegt. Ein Java Threads führt diese einzelnen elementaren Anweisungen einer Methode und die Anweisungen der darin aufgerufenen Methoden sequentiell aus. Die elementaren Anweisungen sind als Aktionen des Teilprozesses zu sehen. Bei Applets startet der Internet Browser ein Java Programm. Für jedes Applet wird ein eigener Thread erzeugt, der dann die Methode init() ausführt. Mehrere Applets laufen immer gemeinsam innerhalb des vom Browser erzeugten Prozesses. Innerhalb eines Java Programms ist es möglich mit Hilfe der Klasse Thread weitere nebenläufige Threads zu erzeugen. Mehrere Threads laufen parallel ab. Sie können gleichzeitig auf gleiche Objekte und Daten zugreifen. Dadurch kann es zu der, in der Vorlesung erwähnten Konflikte, kommen. Auf die Konflikte und wie sie gelöst werden, wird später detailliert eingegangen. Mehrere Threads in einem Programm werden gebraucht, um mehrere Aufgaben parallel zu erledigen. Beispiele: In einem Textprogramm wird ein Druckauftrag erteilt. Mit dem Editieren kann fortgefahren werden. Im Hintergrund wird die Aufbereitung des Textes für den Drucker erledigt. In einer Anwendung zum Erfassen und Pflegen von Daten kann in einer Maske eine Suche gestartet werden. In einer anderen Maske können währenddessen Daten weiter editiert werden. 2 / 28

3 Java Threads und das Betriebssystem Java Prozesse werden auf Betriebssystem Prozesse abgebildet. Sie stellen in Java streng getrennte Bereiche dar. So kann ein Thread eines Java Prozesses nie auf Objekte in anderen Prozessen zugreifen. Eine Kommunikation ist nicht direkt, sondern nur über Verteilungstechnologien wie CORBA oder DCOM, möglich. Diese basieren indirekt auf Netzwerkdiensten des Betriebsystems. Die Java Threads können von der virtuellen Maschine auf Betriebsystem Threads abgebildet werden. Man spricht von einer VM, die native threads unterstützt. Dies ist jedoch nicht immer der Fall. Die meisten ersten Unix Implementierungen der VM verwenden noch ein eigenes Betriebssystem unabhängiges Verfahren, häufig green threads genannt. Dabei werden Threads simuliert. Diese Simulation benutzt ein speziellen Scheduler, der die Reihenfolge der Ausführung festlegt, und oft zu einem unerwarteten und manchmal unerwünschten deterministischen Verhalten. (Siehe auch 4. Zuteilungsstrategien in Java) 2.1 Die Klasse Thread Java bietet eine Klasse Thread an, die einen Thread repräsentiert. Mit Hilfe dieser Klasse können Threads erzeugt werden. Es werden hier nur die wichtigsten Methoden besprochen. 2.2 Der aktuelle Thread Die statische Methode currentthread() liefert den Zugriff auf den aktuellen Thread, der die Methode gerade ausführt. Ein einfaches Programm, das den aktuellen Thread am Bildschirm ausgibt: public class ThreadTest public static void main( String[] arguments ) System.out.println("THREAD:" + Thread.currentThread() ); Am Ende der Methode main() ist auch der Thread und damit der Prozeß beendet. Ausgabe am Bildschirm: THREAD:Thread[main,5,main] Hinter dem Text THREAD: steht, das was die Methode tostring() der Klasse Thread zurück liefert. Das sind der Name, die Priorität und die Thread Gruppe. Auf die Priorität und Gruppe wird später unter 4. genauer eingegangen, sie sind zunächst unwichtig. 3 / 28

4 2.3 Mehrere Threads Jetzt fügen wir eine Klasse Counter hinzu mit einer Methode run(). Die Methode soll die Zahl 0 bis einschließlich 1000 ausgeben. Weiterhin erzeugen wir einen zweiten Thread, um zweimal parallel die Methode run() auszuführen. Die Klasse Counter implementiert die Schnittstelle Runnable um damit die Methode run() für Threads als die auszuführende Methode anzugeben. class Counter implements Runnable public void run() Thread thread = Thread.currentThread(); for( long count = 0 ; count <= 1000 ; ++count ) System.out.println( thread + "COUNT:" + count ); public class MultipleThreadTest public static void main( String[] arguments ) Counter counter = new Counter(); Thread secondthread = new Thread( counter, "second" ); secondthread.start(); counter.run(); Der Haupt Thread legt in der Methode main() zunächst ein Objekt counter der Klasse Counter als Zähler an. Ein zweites Thread Objekt, secondthread, wird erzeugt und dabei wird der Zähler mitgegeben. Mit start() startet der Haupt Thread den zweiten Thread. Dieser ruft intern die run() Methode des Zählers auf. Der Haupt Thread läuft parallel weiter und ruft selbst auch die run() Methode auf. Die Methode run() wird jetzt parallel von zwei Threads ausgeführt. Jeder Thread arbeitet seine eigene Schleife ab. Der Schleifen Zähler, bzw. den Zählerstand, count, ist eine lokale Variable der Methode run() und wird auf dem Stack abgelegt. Jeder Thread besitzt sein eigenen Stack. Damit existiert der Zählerstand jetzt zweimal. Auszug aus einer möglichen Ausgabe: Thread[second,5,main]COUNT:95 Thread[second,5,main]COUNT:96 Thread[second,5,main]COUNT:97 Thread[main,5,main]COUNT:95 Thread[second,5,main]COUNT:98 Thread[main,5,main]COUNT:96 Thread[second,5,main]COUNT:99 4 / 28

5 Thread[main,5,main]COUNT:97 Thread[second,5,main]COUNT:100 Thread[main,5,main]COUNT:98 Thread[second,5,main]COUNT:101 Thread[main,5,main]COUNT:99 Thread[second,5,main]COUNT:102 Thread[main,5,main]COUNT:100 Thread[second,5,main]COUNT:103 Thread[main,5,main]COUNT:101 Thread[main,5,main]COUNT:102 Thread[main,5,main]COUNT:103 Bemerkung zu den Ausgaben Da ein regelmäßiges Abwechseln von Threads für eine Implementierung einer Java VM nicht vorgeschrieben ist, können die Ausgaben immer gleich sequentiell erscheinen. Verwenden Sie für ein weniger deterministisches Verhalten den RoundRobinScheduler aus 4.1 Zeitscheibenstrategie und schreiben Sie in die erste Zeile der Methode main() : new RoundRobinScheduler(10).start(); Bemerkung zur Methode run() Die Signatur der Methode public void run() wird durch die Schnittstelle Runnable vorgegeben. Diese Schnittstelle wird von der Klasse Thread vorausgesetzt. Man hat grundsätzlich die Wahl, von der Klasse Thread abzuleiten und dessen Methode run() zu überschreiben, oder die Schnittstelle Runnable zu implementieren und dann beim Erzeugen eines Threads das ausführbare Objekt anzugeben. Die Methode run() hat keine Parameter, daher müssen benötigte Daten anderweitig weitergereicht werden. Beispielsweise über Attribute des Objektes, das die Runnable Schnittstelle implementiert. Bemerkung zu JDK 1.2 Einige Methoden der Klasse Thread werden ab Java 1.2 nicht mehr unterstützt: Die Methode stop() und suspend() gaben keine Sperren frei und konnten somit einfach eine Verklemmung produzieren. Die Methode resume() machte ohne die Methode suspend() keinen Sinn mehr. Sperren und Verklemmung werden noch genauer besprochen. 2.4 Mehrere Threads mit gemeinsamen Variablen Wir ändern die Klasse Counter so ab, daß der Zählerstand count ein Attribut wird. Beide Threads versuchen ihrerseits den Zählerstand zu inkrementieren. Ziel ist, daß beide gemeinsam den Zähler von 0 auf 1000 hochzählen. 5 / 28

6 class Counter implements Runnable private long count = 0; public void run() Thread thread = Thread.currentThread(); for( ; count <= 1000 ; ++count ) System.out.println( thread + "COUNT:" + count ); Auszüge aus einer mögliche Ausgabe:... Thread[main,5,main]COUNT:44 Thread[main,5,main]COUNT:45 Thread[main,5,main]COUNT:46 Thread[main,5,main]COUNT:47 Thread[main,5,main]COUNT:48 Thread[main,5,main]COUNT:49 Thread[second,5,main]COUNT:49!!! Thread[main,5,main]COUNT:50 Thread[second,5,main]COUNT:51 Thread[main,5,main]COUNT:52... Thread[second,5,main]COUNT:995 Thread[second,5,main]COUNT:996 Thread[second,5,main]COUNT:997 Thread[second,5,main]COUNT:998 Thread[second,5,main]COUNT:999 Thread[second,5,main]COUNT:1000 Thread[main,5,main]COUNT:1001!!!!! Diese Ausgaben sind, wenn man den Code sieht, nicht direkt plausibel. Was ist z.b. bei der letzten Ausgabe 1001 passiert? Sei count = 999. Jetzt kann folgender Ablauf stattfinden: Der Haupt Thread "main" prüft ob count <= 1000 ist. Dies ist der Fall. Jetzt kommt Thread "second" an dieser Stelle an und prüft ebenfalls ob count <= 1000 ist. Dies ist der Fall und count wird inkrementiert und ausgegeben. Der Haupt Thread inkrementiert count ebenfalls und gibt ihn aus. Das Attribut count war inzwischen jedoch bereits von "second" inkrementiert worden, somit ist der Wert jetzt 1001! Offensichtlich ist es notwendig, beide Threads zu koordinieren. Sie müssen so synchronisiert werden, daß nur ein Thread das Prüfen der Bedingung und die Inkrementierung atomar, d.h. vollständig ohne Unterbrechung, ausführt. 6 / 28

7 Wie immer bei fehlender Synchronisation muß der im Beispiel gezeigte Fehler nicht zwingend auftreten und kann lange Zeit völlig unbemerkt bleiben. Je nachdem, wann die Threads aktiv sind bzw. bei einem Prozessor sich abwechseln, ergeben sich unterschiedliche Resultate. Dies macht es extrem schwer in einem fertigen System fehlerhafte Code Stellen zu finden. Vor allem kann allein das Suchen eines Fehlers mit Hilfe des Debuggers, den Fehler verschwinden lassen. Durch die Beobachtung mit dem Debugger wird das Abwechseln der Threads beeinflußt. 3 Synchronisation paralleler Threads in Java Mehrere Threads können nur über gemeinsame Variablen kommunizieren. Java stellt keine anderen Kommunikationsmittel zur Verfügung. Folgende Konflikte können dabei auftauchen: Gleichzeitiges Lesen und Schreiben. Ein Thread liest und ein anderer ändert gerade das Objekt, ist aber noch nicht fertig. Gleichzeitiges Schreiben. Mehrere versuchen das Objekt gleichzeitig zu ändern. Gemeinsam benutzte Objekte sollten aus der Sicht eines Threads einen korrekten konsistenten Zustand haben. Der Zustand eines Objektes besteht aus den Werten seiner Attribute und den Zuständen der enthaltenen Objekte. Das Ausführen einer Methode kann den Zustand eines Objektes ändern. Eine Methode sollte das Objekt von einem stabilen korrekten Zustand in einen anderen stabilen korrekten Zustand überführen. Beim Übergang von einem Zustand in einem anderen Zustand können Zwischenzustände auftreten, die nach außen nicht sichtbar werden sollen. Sie sind in der Regel von der Implementierung der Methode abhängig. Rufen mehrere Threads Methoden gleichzeitig auf, dann kann ohne Synchronisation ein Zwischenzustand einer Methode den Ablauf einer anderen Methode beeinflussen. Um Konflikte zwischen Threads zu vermeiden gibt es verschiedene Möglichkeiten. Schreiben nicht zulassen Eine Klasse wird so definiert, daß eine Änderung seiner Attribute nach dem Erzeugen der Objekte nicht mehr möglich ist. ( engl. immutable class). Dies scheint eine drastische Einschränkung, kann aber in manchen Fällen durchaus sinnvoll sein. Vor allem, wenn ein Objekt einen Wert darstellt und die Identität nicht wesentlich ist, kann man sich die meist zeitintensive Synchronisation sparen. Bei Java können z.b. mehrere Threads problemlos auf ein gleiches Objekt der Klasse java.lang.string zugreifen, da ein String nie mehr geändert werden kann. Jede Methode der Klasse produziert bei einer Änderung des Wertes ein neues String Objekt. Für eine performante Änderung eines String steht die Klasse java.lang.stringbuffer zur Verfügung, diese ist aber nicht sicher für die gleichzeitige Verwendung durch mehrere Threads. (engl. thread safe) 7 / 28

8 Lesen und Schreiben synchronisieren Für die meisten Objekte jedoch ist die Identität wichtig. Nur eine explizite Synchronisation, die nachfolgend erläutert wird, kann Konflikte vermeiden. Die Sperre Java verknüpft jede Instanz der Klasse java.lang.object mit einer sogenannten Sperre ( engl. lock). Jedes Objekt ist in Java direkt oder indirekt von der Klasse java.lang.object abgeleitet, somit ist mit jedem Objekt genau eine Sperre verknüpft. Diese Sperre entspricht einem Booleschen Semaphor. Eine Sperre wird einem einzigen Thread zugeteilt. Die anderen Threads müssen gegebenenfalls warten, bis der Thread die Sperre wieder freigibt. Mit diesem gegenseitigen Ausschluß (engl. mutually exclusive lock kurz mutex lock) lassen sich Zugriffe auf Objekte so koordinieren, daß Konflikte vermieden werden. Betrachten wir einen Bereich, in dem gemeinsame Variablen geschrieben oder gelesen werden. Benötigt jeder Thread eine Sperre bevor er diesen Bereich ausführt und gibt er danach die Sperre wieder frei, dann kann zu jedem Zeitpunkt nur ein einziger Thread in dem Bereich aktiv sein. Somit ist ein gleichzeitiges Lesen und Scheiben oder ein gleichzeitiges Schreiben der gemeinsamen Variablen in diesem Bereich unmöglich. In Java müssen alle Bereiche, in dem gemeinsame Variablen geschrieben oder gelesen werden, explizit mit dem Schlüsselwort synchronized versehen werden, um Konflikte zu vermeiden. Sei O ein beliebiger Ausdruck, der ein Java Objekt liefert, und S eine Menge von Anweisungen, dann ist die Syntax: synchronized( O ) S Erreicht ein Thread die synchronized Anweisung, dann gelten folgende Regeln: Der Thread versucht den exklusiven Zugriff auf das Objekt O zu erhalten. Wenn kein anderer Thread den exklusiven Zugriff hat, gelingt dies. Besitzt ein anderer Thread den exklusiven Zugriff auf das Objekt, dann wartet der Thread, bis das Objekt O freigegeben wird. Es können mehrere Threads auf die Freigabe warten. (Siehe auch 3. Zuteilungstrategien). Erhält ein Thread den exklusiven Zugriff auf O, dann tritt er in den Anweisungsblock ein. Verläßt der Thread den Anweisungsblock, in dem er den exklusiven Zugriff erhalten hat, dann gibt er das Objekt O wieder frei. Die mit einem Objekt verknüpfte Sperre ist sonst nicht direkt zugänglich und kann nur mit dem Schlüsselwort synchronized gesetzt und freigegeben werden. 8 / 28

9 Ausnahmebehandlung Achtung: Wenn eine Ausnahme ( engl. exception) auftritt, die nicht innerhalb eines Anweisungsblocks abgefangen wird, dann wird wie üblich der Anweisungsblock automatisch verlassen und dabei auch die Sperre freigegeben. Daher sollte man auch nach einer Ausnahme einen konsistenten Zustand hinterlassen. Verschachtelte synchronized Anweisungsblöcke Verschachteln von synchronisierten Anweisungsblöcken ist möglich, auch wenn mehrmals mit dem gleichen Objekt synchronisiert wird: Wenn ein synchronisierter Anweisungsblock erreicht wird, kann es also sein, daß der Thread bereits den Zugriff auf das Objekt hat. Dann kann der Thread sofort in dem Anweisungsblock eintreten. Beim Verlassen dieses Anweisungsblocks, wird das Objekt noch nicht freigegeben. Erst beim Verlassen des äußeren Anweisungsblocks, dort wo er den Zugriff ursprünglich erhalten hat, wird das Objekt freigegeben. Damit wird verhindert, daß ein Thread auf sich selbst wartet. Mit einem synchronized Block wird also gewährleistet, daß nur ein Thread in dem Anweisungsblock zu einem Zeitpunkt aktiv sein kann. 3.1 Kritischer Bereich Wir können jetzt das synchronized Schlüsselwort einsetzen, um den vorher beim Zählerstand gezeigten Fehler zu beheben. Die Prüfung und die Inkrementierung stellen einen sogenannten kritischen Bereich dar. Dies ist ein Bereich, wo Konflikte zwischen Threads auftreten können. Wir ändern jetzt den Code so ab, daß die Prüfung und die Inkrementierung nur zusammen ausgeführt werden können. class Counter implements Runnable private long count = 0 ; public void run() Thread thread = Thread.currentThread(); boolean bcontinue = true; while ( bcontinue ) System.out.println( thread + "COUNT:" + count ); synchronized( this ) if( count < 1000 ) ++count; else bcontinue = false; 9 / 28

10 Warum wurde this angegeben? Das Attribut count kann man nicht angeben. Der Typ von count ist long. Dieser Typ ist ein sogenannter primitiver Typ, wie auch short, int, byte, char, float und double. Damit ist count kein Objekt. Allerdings ist count ein Attribut von der Klasse Counter. Folglich gehört zu jedem Attribut namens count genau ein Objekt der Klasse Counter. Daher ist es einfach das Attribut count mit dem zugehörigen Objekt zu synchronisieren. Das Objekt wird in der Methode mit this angegeben. Die for Schleife wurde in eine while Schleife geändert, damit die Prüfung und die Inkrementierung in einem Block innerhalb der Schleife stattfinden können. Was passiert, wenn der synchronisierte Anweisungsblock die gesamte for Schleife umfassen würde? Warum ist es Problematisch, daß die Ausgabe außerhalb des synchronized Bereiches gemacht wird? Synchronisierte Methoden Wir ändern die Klasse Counter jetzt so, daß die Prüfung und das Inkrementieren in einer eigenen increment() Methode passieren. Der Rückgabewert gibt an, ob eine Inkrementierung möglich war. class Counter implements Runnable private long count = 0 ; public void run() Thread thread = Thread.currentThread(); boolean bcontinue = true; while ( bcontinue ) System.out.println( thread + "COUNT:" + count ); bcontinue = increment(); public boolean increment() synchronized( this ) if ( count < 1000 ) ++count; return true; return false; Jetzt ist die gesamte Implementierung der Methode increment() synchronisiert. Java erlaubt dafür folgende semantisch äquivalente Schreibweise: 10 / 28

11 Wir ändern die Methode increment() ab: public synchronized boolean increment() if ( count <= 1000 ) ++count; return true; return false; Dies wird eine synchronisierte Methode genannt. Es wird gewährleistet, daß nur ein Thread gleichzeitig in genau dieser Methode aktiv sein kann. Es wird nicht gewährleistet, daß kein anderer Thread gleichzeitig in einer anderen Methode aktiv ist. D.h. count kann in einer anderen Methode weiterhin gleichzeitig geändert werden. Lesende Methoden müssen synchronisiert werden Wir führen ein Methode getcount() ein, die den Zählerstand zurück liefert. public long getcount() return count; Nehmen wir an, ein Thread ruft irgendwann getcount() auf. Auf den ersten Blick ist nicht ersichtlich, daß hier ein Problem vorliegt. Die Methode getcount() kann ein fehlerhaftes Ergebnis haben und zwar aus zwei folgenden Gründen: getcount() kann ausgeführt werden, während irgendeine andere auch synchronisierte Methode z.b increment() oder eine andere Methode aus einer Subklasse ausgeführt wird. Diese andere Methode könnte count in ihrem Ablauf zwischenzeitlich auf den Wert 1 setzen und erst am Ende den korrekten Wert zuweisen. Die Methode getcount() könnte dann zwischenzeitlich den unsinnigen Wert 1 liefern. Auch wenn keiner den Wert zwischenzeitlich auf 1 setzt, kann getcount() einen falschen Wert liefern. Java garantiert, daß alle Operationen auf primitive Typen atomar ausgeführt werden, außer für double und long. D.h. Die Ausführung von ++count, könnte in 2 Schritten ablaufen. Zwischen diesen beiden Schritten kann ein Threadwechsel auftreten. Der Wert von count nach dem 1. Schritt ist nicht spezifiziert. Was wir eigentlich erreichen wollten ist eine immer konsistente Sicht auf Counter von außen. Daher muß auch getcount() synchronisiert werden: 11 / 28

12 public synchronized long getcount() return count; Damit ist auch klar, warum eine Methode getcount() unerläßlich ist, und count nicht einfach public gemacht werden kann. Aus der bisherigen Beschreibung ist ersichtlich, daß, um mehrere Threads zu unterstützen, wesentliche Codeänderungen notwendig waren. Vollständig synchronisierte Klassen Sind in einer Klasse alle nicht statischen Methoden über dasselbe Objekt synchronisiert und alle Attribute private, dann kann ein Objekt dieser Klasse nur von jeweils einem Thread bearbeitet werden. Dies entspricht dem Konzept des Monitors, bei dem nur eine Operation eines Monitors gleichzeitig ausgeführt werden kann. Die beim Monitor üblichen Benachrichtigungsmechanismen existieren auch in Java. Sie werden anschließend im Abschnitt 2.3 erläutert. Synchronisation statischer Methoden In Java gehört zu jeder Klasse eine, vom System erzeugte Instanz der Klasse java.lang.class. Diese Instanz beschreibt den Aufbau der Klasse und macht diese zur Laufzeit verfügbar. Der Klassenname gefolgt von.class,liefert diese Instanz. Wenn eine statische Methode als synchronized gekennzeichnet wird, dann entspricht dies einer Synchronisierung mit der zu dieser Klasse gehörenden Instanz der Klasse java.lang.class. Beispiel: public class Counter private static long maximum = 1000; public static synchronized long getmaximum() return maximum; Die Methode getmaximum() entspricht folgender Implementierung: public static long getmaximum() synchronized( Counter.class ) return maximum; 12 / 28

13 Synchronisierte Methoden und Vererbung. Die Synchronisation gehört in Java nur zur Implementierung und wird nicht vererbt! Daher kann auch eine Schnittstellen Definition nicht das Schlüsselwort synchronized enthalten. Beim überschreiben einer Methode, darf daher die Synchronisation bei der neuen Implementierung nicht vergessen werden. 3.2 Bewachte kritische Bereiche Bisher konnte ein Thread nur auf eine einzige Bedingung warten. Und zwar darauf, ob ein Zugriff zur Verfügung steht oder nicht. Manchmal jedoch möchte man komplexere zustandsabhängige Bedingungen formulieren auf deren Erfüllung man wartet. Man spricht dann von einem bewachten kritischen Bereich. Ein Thread wartet bis eine Bedingung erfüllt ist, bevor er in dem Bereich eintritt. ( engl. guarded suspension) In der Vorlesung wurde dies durch await E then S endwait zum Ausdruck gebracht. Wobei E einen booleschen Ausdruck und S eine Menge von Anweisungen ist. Der Ausdruck E stellt den Wächter ( engl.guard ) dar. Sobald E erfüllt ist, wird S exklusiv von einem einzigen Thread ausgeführt. Die exklusive Ausführung wird in Java durch das Schlüsselwort synchronized erreicht. Das Warten, hier auf eine Bedingung, wird durch ein Aufruf der Methode wait() eines Objektes eingeleitet: public class ClassWithGuardedSuspension private synchronized void awaitconditione() while(! E ) try wait(); catch( InterruptedException ex ) public void synchronized guardedstatementss() awaitconditione(); S 13 / 28

14 Wozu wird wait() gebraucht? Würde man statt wait() eine Schleife wie while(!e) verwenden, dann spricht man von busy waiting. Der Thread wertet die ganze Zeit, meistens unnötigerweise, die Bedingung aus. Weiterhin wird dabei die Sperre nicht abgegeben. Dadurch kann ein anderer Thread nie an die Reihe kommen, um den Zustand so zu ändern, daß die Bedingung jemals wahr wird! Busy waiting ist folglich zu vermeiden. Ein wartender Thread muß auch benachrichtigt (engl. notified) werden, daß er weiter machen kann. Daher existieren folgende vom Laufzeitsystem vorgegeben Methoden der Klasse Object: wait() notify() notifyall() Nur wenn ein Thread den exklusiven Zugriff auf ein Objekt hat, kann er dessen wait(), notify() oder notifyall() Methode aufrufen. Ansonsten wird ein IllegalMonitorStateException vom Laufzeitsystem erzeugt. wait() Der aktuelle Thread wird auf wartend gesetzt und in einem mit dem Objekt verknüpften Wartebereich gestellt Den exklusiven Zugriff, den der Thread hat, wird freigegeben. Was Voraussetzung daf ür ist, daß andere Threads überhaupt notify() oder notifyall() aufrufen können. notify() Wenn wartende Threads existieren, dann wird nichtdeterministisch einer ausgewählt und dieser aus dem Wartebereich entfernt. Der ausgewählte Thread versucht Zugriff auf das Objekt zu bekommen. Der ausgewählte Thread kann den Zugriff nur dann bekommen, wenn der Thread der notify() aufgerufen hat und noch im Besitz des Zugriffs, diesen freigibt und kein anderer Thread den Zugriff erhält. Erhält der ausgewählter Thread später den Zugriff, dann setzt er die Ausführung mit dem auf wait() folgendem Code fort. notifyall() Verläuft wie notify() mit dem Unterschied, daß alle wartenden Threads aus dem Wartebereich entfernt werden und wieder versuchen die Sperre zu bekommen. Es existiert noch die Möglichkeit bei wait() die maximale Wartezeit anzugeben. Ist diese verstrichen, dann wird automatisch für diesen Thread wie bei notify() verfahren. Wenn ein Unterbrechung ( engl. interrupt) während eines wait() passiert ( z.b. durch Aufruf der interrupt() Methode der Klasse Thread), dann wird wie bei notify() verfahren. Die Ausführung wird aber fortgefahren mit dem Werfen einer Ausnahme der Klasse InterruptedException. Das Ziel ist es mit wait() auf ein Ereignis zu warten. Das Ereignis wird durch das Objekt oder einen Zustand des Objektes repräsentiert. Mit notify() wird dann das Eintreten des Ereignisses mitgeteilt. 14 / 28

15 Da die Auswahl der Threads beim notify() nichtdeterministisch ist, kann es zum Aushungern kommen. D.h. bestimmte Threads werden nie aus dem Wartbereich ausgewählt. Nur eine selbst programmierte Warteschlange kann hier Fairness garantieren. (siehe auch ) Somit kann jedes Java Objekt als Signal, wie beim Monitorkonzept in der Vorlesung definiert, verwendet werden. 3.3 Das Monitor Konzept in Java Das Monitor Konzept der Vorlesung läßt sich in Java realisieren durch eine Klasse, in der alle Attribute private sind, alle nicht statischen Methoden als synchronized gekennzeichnet sind und das Objekt selbst immer als Signal verwendet wird: Die Kennzeichnung aller Methoden als synchronized garantiert den gegenseitigen Ausschluß. Die Verwendung des Objektes selbst als Signal, sorgt für eine Freigabe der Sperre beim wait(), und ermöglicht damit die Ausführung der Methoden durch andere Threads. Bei der Verwendung als Signal, wird für ein Objekt o in der Regel angenommen, daß man beim Aufruf von o.wait() auf eine Zustandsänderung von o wartet. Bei o.notify() gibt man dann die Zustandsänderung bekannt. Diese Interpretation ist jedoch nicht zwingend. Beispiel für einen Monitor unter Verwendung von wait() und notifyall(): Wir ändern jetzt increment(), so daß inkrementiert wird, sobald dies möglich ist. Der Rückgabewert ist damit überflüssig. Analog zu increment() führen wir eine Methode decrement() und ein Minimum ein. Die Methode decrement() versucht zu dekrementieren, sobald dies möglich ist. Dann lassen wir einen Thread hochzählen und einen anderen Thread runterzählen. public class Counter private static long maximum = 1000; private static long minimum = 0; public static synchronized long getmaximum() return maximum; public static synchronized long getminimum() return minimum; private long count = getminimum(); private synchronized void awaitincrementable() while(!( count < getmaximum() ) ) try wait(); 15 / 28

16 catch( InterruptedException e ) public synchronized void increment() awaitincrementable(); setcount( count +1 ); private synchronized void awaitdecrementable() while(!( count > getminimum() ) ) try wait(); catch( InterruptedException e ) public synchronized void decrement() awaitdecrementable(); setcount( count 1 ); public synchronized void setcount( long count ) this.count = count; System.out.println( Thread.currentThread() + "COUNT:" + count ); notifyall(); public synchronized long getcount() return count; public class CounterTest public static void main( String[] arguments ) final Counter counter = new Counter(); Thread secondthread = new Thread( "second" ) public void run() while ( true ) counter.increment(); ; secondthread.start(); while( true ) counter.decrement(); 16 / 28

17 Jedesmal wenn count sich ändert, wird setcount und damit notifyall() aufgerufen. Ein Thread der z.b. bei einem awaitincrementable wartet, wird dann geweckt. Ist der count < maximum, dann wird inkrementiert. Warum wird die Bedingung in einer Schleife geprüft? Der notifyall() deutet nur eine Änderung an. Nach einem notifyall() ist keineswegs die Erfüllung der Bedingung gewährleistet. Warum wird notifyall() verwendet? Der Aufruf von notify() statt notifyall(), ist nur dann zu empfehlen, wenn es nur eine Bedingung gibt und nachher garantiert ist, daß nur ein einziger Thread aktiv werden kann. Wie kann die Anzahl der notify() Aufrufe und der damit verbundene Synchronisationsaufwand reduziert werden? Hinweis: Wenn der Zustandsraum aufgeteilt wird, ergeben sich nur bestimmte Situationen, wo ein notifyall() sinnvoll ist. Bemerkungen Unsere Klasse Counter ist ein Monitor im Sinne der Vorlesung. Wenn in einer synchronisierten Methode ein wait() aufgerufen wird, dann kann die Operation nicht mehr als atomar betrachtet werden! Beim wait() wird die Sperre freigegeben und andere Threads können den Zustand ändern. Daher sollte das Objekt in einen konsistenten Zustand sein bevor wait() aufgerufen wird. Am einfachsten ist dies dadurch zu erreichen, indem vor einem wait() keine Änderungen am Objekt gemacht werden. Wird der Zustand so geändert, daß ein anderer Thread weitermachen könnte, ruft man notifyall() oder notify() auf. Danach sollte der Thread, solange er den Zugriff hat, den Zustand nicht mehr ändern. Die geweckten Threads können erst nach der Freigabe der Sperre aktiv werden und nicht schon unmittelbar nach dem notifyall() Aufruf. Ein geweckter Thread findet dann vielleicht einen Zustand vor, in dem die Bedingung eventuell nicht mehr erfüllt ist. Am einfachsten ist es, wenn ein notify() Aufruf als möglichst letzter Aufruf vor dem Verlassen der Methode verwendet wird. Eine Nachrichtenschlange in Java Ein Sender und Empfänger kommunizieren über eine Nachrichtenschlange. Der Empfänger soll so lange warten bis ein Objekt vorliegt. public class MessageQueue private Vector queue = new Vector(); public synchronized void send( Object object ) queue.addelement( object ); notifyall(); 17 / 28

18 public synchronized Object receive() while( queue.size() == 0 ) try wait(); catch( InterruptedException e ) Object object = queue.elementat(0); queue.removeelementat(0); return object; // send a string character by character in an endless loop public class Sender extends Thread private String text; private MessageQueue messagequeue; public Sender( String text, MessageQueue messagequeue ) super( "sender of " + text ); this.text = text; this.messagequeue = messagequeue; public void run() while ( true ) for( int i = 0 ; i < text.length() ; ++i ) messagequeue.send( text.substring( i,i+1 ) ); public class MessageQueueTest public static void main( String[] arguments ) MessageQueue messagequeue = new MessageQueue(); Thread sosthread = new Sender( "S.O.S!!!", messagequeue ); sosthread.start(); Thread hellothread = new Sender( "Hello??", messagequeue ); hellothread.start(); while ( true ) System.out.print( messagequeue.receive() ); ; Beachte die Analogie der Klasse MessageQueue und der Klasse Counter aus dem vorangehenden Beispiel. Erweiteren Sie die Klasse MessageQueue so, daß die Nachrichtenschlange nur eine maximale Anzahl an Elementen beinhalten kann. 18 / 28

19 3.4 Semaphore Mit bewachten kritischen Bereiche können, analog zu den Definitionen der Vorlesung, auch Semaphore in Java umgesetzt werden. In der Regel ist eine direkte Verwendung der bestehenden Synchronisationsmechanismen jedoch einfacher Ganzzahlige Semaphore Die ganzzahligen Semaphore lassen sich wie folgt realisieren: public final class CountingSemaphore private int count = 0; public CountingSemaphore( int initialcount ) count = initialcount; public synchronized void P() while( count <= 0 ) try wait(); catch( InterruptedException ex ) count; public synchronized void V() ++count; notify(); Der Aufruf von notify() statt notifyall() ist ausreichend, da nur ein einziger Thread nach der Freigabe aktiv werden kann: Dieser nimmt sofort die frei gewordene Ressource und die anderen müssen weiterhin warten Boolesche Semaphore Die boolesche Semaphore werden analog zu den ganzzahligen Semaphoren implementiert: public final class BooleanSemaphore private boolean isfree; public BooleanSemaphore( boolean isfree ) this.isfree = isfree; 19 / 28

20 public synchronized void P() while(!isfree ) try wait(); catch( InterruptedException ex ) isfree = false; public synchronized void V() isfree = true; notify(); 3.5 Verklemmung Koch Beispiel Eine Verklemmung kann leicht auftreten, falls mehrere Threads die gleichen Objekte als Ressourcen in einer verschiedenen Reihenfolge verwenden. Nehmen wir an, es stehen in einer Küche nur eine Schüssel und nur ein Maßbecher sowie weitere übliche Utensilien zur Verfügung. Nehmen wir weiterhin an, ein Koch kann mehrere Omelettes machen: Er nimmt eine Schüssel, füllt die Schüssel mit aufgeschlagenen Eiern und rührt diese. Mit einem Maßbecher mißt er ab, wieviel er für jedes Omelett braucht. Er backt die einzelnen Omeletts in der Pfanne. Ein Koch kann auch Kekse machen: Er nimmt einen Maßbecher, um die Menge an Mehl zu bestimmen. Er gibt den Inhalt des Maßbechers in eine Schüssel und rührt die Ingredienzen zusammen. Anschließend formt er die Kekse und backt sie im Backofen. Das ganze in pseudo Java Code: 20 / 28

21 class Koch static Schuessel schuessel; static Massbecher massbecher; static Mehl mehl; static Ei[] eier;... void macheomeletts( int anzahl ) synchronized( schuessel ) schuessel.fuellemit( brecheeier( eier ) ); schuessel.ruehren(); synchronized( massbecher ) massbecher.fuellemit( schuessel.inhalt() ); massbecher.messeanteil(anzahl);... void machekekse() synchronized( massbecher ) massbecher.messe( mehl ); synchronized( schuessel ) schuessel.fuelle( massbecher ); schuessel.ruehren();... Nehmen wir an es gibt zwei Köche, Hugo und Fritz. Koch Hugo macht Omeletts und Koch Fritz macht Kekse. Wenn zwei Köche sich gleichzeitig in der Küche aufhalten, dann muß eine Koordination stattfinden. Die allererste selbstverständliche Koordination, die uns einfällt ist, daß die Schüssel nicht von mehreren Köchen gleichzeitig verwendet wird, sondern nur exklusiv von einem Koch. Analoges gilt für den Maßbecher. Ansonsten könnte es passieren, daß die Ingredienzen der Kekse und der Omeletts unkontrolliert vermischt werden. Ein Koch wartet sozusagen als Thread auf eine Freigabe der Schüssel. Dennoch ist diese Koordination nicht ausreichend, die Reihenfolge ist entscheidend. Folgende Situation kann auftreten: Hugo nimmt eine Schüssel, füllt diese mit Eiern. Fritz nimmt gleichzeitig den Maßbecher und mißt Mehl ab. Hugo möchte jetzt abmessen wieviel er für jedes Omelett braucht. Er braucht den Maßbecher, der ist leider noch in Gebrauch. Fritz möchte jetzt die Schüssel nehmen, um das Mehl rein zu geben, die ist leider noch in Gebrauch. 21 / 28

22 Beide warten endlos aufeinander. Ein Verklemmung ist aufgetreten. (engl. deadlock) Mögliche Lösungen sind: Es darf nur ein Koch gleichzeitig in die Küche. Damit erhöht man die Sperr Granularität. Dies verringert die Nebenläufigkeit. Oder die Köche reservieren die benötigten Utensilien immer in der gleichen Reihenfolge. Dadurch wird implizit eine Sperren Hierarchie vorgeschrieben. Bei einer Verklemmung wird von einer übergeordneten Instanz die Verklemmung aufgelöst. Ein Koch muß die Zwischenergebnisse verwerfen und neu anfangen. Diese Möglichkeit wird von Java selbst nicht unterstützt Verschachteltes Monitor Problem Eine Klasse wie die MessageQueue ist ein Monitor. Beinhaltet ein Monitor ein weiteren Monitor und ist dieser nur über den äußeren Monitor zugänglich, dann kann es ebenfalls leicht zu einer Verklemmung (engl. deadlock) kommen. Wir ändern jetzt die Klasse MessageQueue so ab, daß das Signal Die Nachrichtenschlange ist nicht leer, durch eine Boolesche Semaphore dargestellt wird. public class MessageQueue private Vector queue = new Vector(); private BooleanSemaphore nonempty = new BooleanSemaphore( false ); public synchronized void send( Object object ) queue.addelement( object ); nonempty.v(); public synchronized Object receive() nonempty.p(); Object object = queue.elementat(0); queue.removeelementat(0); return object; Wenn ein Thread receive() aufruft und wenn die Schlange leer ist, dann wird beim wait(); in der Methode P() nur die Sperre für die Semaphore freigegeben, nicht die Sperre der MessageQueue. Dadurch kann ein anderer Thread nicht in send() eintreten, d.h. nie mehr eine Nachricht in die Schlange stellen und den Thread, der in P() wartet, nie mehr benachrichtigen. Der Empfänger sperrt somit den Sender aus ( engl. lock out ) Das Problem läßt sich lösen indem: entweder synchronized beim äußeren Objekt entfernt wird, falls dies möglich ist. Oder indem man dem inneren aggregierten Objekt einen Verweis auf das Äußere mitgibt. Somit könnte das innere Objekt das äußere Objekt für die Synchronisation verwenden. Dies bedingt aber eine Codeänderung der Klasse BooleanSemaphore! 22 / 28

23 4 Zuteilungsstrategien in Java für Threads Bisher wurde nur von mehreren gleichzeitig aktiven oder wartenden Threads ausgegangen. Thread benötigen für ihre Ausführung einen Prozessor. Viele Java Implementierungen unterstützen bisher nur einen Prozessor. Bei nur einem Prozessor, kann nur ein Thread aktiv sein. Der Thread wird dem Prozessor zugeteilt. Man spricht auch von Scheduling (engl.). Die Zuteilungsstrategie beeinflußt wesentlich das Verhalten des Systems bei mehreren Threads. Um die Zuteilungsstrategien (engl. scheduling strategies) besser zu verstehen, unterscheiden wir die folgenden Zustände eines Threads: Initialzustand: Der Thread wurde erzeugt, führt aber noch keine Methode aus. d.h. start() wurde noch nicht aufgerufen. Lauffähig: Ein Thread geht vom Initialzustand mit start() in den Zustand Lauffähig über. Aktiv: Ein Thread wird aktiv, wenn er von Javas virtueller Maschine (JVM) dazu aus der Menge der lauffähigen Threads ausgewählt wird. In diesem Zustand führt der Thread tatsächlich Code aus. Der Thread wird vom der JVM dann entweder in den Zustand lauffähig zurück gesetzt oder er kommt in den Zustand Blockiert. Blockiert: Ein Thread ist blockiert, wenn er auf den exklusiven Zugriff auf eines bei synchronized angegeben Objektes oder auf ein Ereignis mittels wait() wartet. Ist ein Thread blockiert, dann geht er in den Zustand Lauffähig über, falls ein anderer Thread die Sperre freigibt oder falls ein anderer Thread mit einem notify() oder notifyall() das Ereignis meldet und daraufhin die JVM den blockierten Thread auswählt. Eine andere Möglichkeit blockiert zu werden, ist der Aufruf der Methode void sleep( long milliseconds ) der Klasse Thread. Wenn die Zeit abgelaufen ist, wird die JVM den Thread wieder in den Zustand Lauffähig setzen. Sperren werden in der Zwischenzeit nicht freigegeben. Endzustand: Ein Thread ist in seinem Endzustand, falls die run() Methode ausgeführt wurde, oder mit einer Ausnahme beendet wurde. 23 / 28

24 Auswahl durch JVM nach notify Intial start() Lauffähig Auswahl durch JVM notify() notifyall() Aktiv Blockiert run(), sleep() oder in synchronized() warten auf den Zugriff Ende von run() oder unbehandelte Ausnahme Ende Dieser Automat zeigt die Übergänge zwischen den Zuständen eines Threads Die entscheidende Frage ist, wie das Java Laufzeitsystem einen Thread zum aktiven Thread bestimmt. Prioritäten Threads können unterschiedliche Prioritäten haben. Diese werden nur vom Programmierer festgelegt. Die Java virtuelle Maschine garantiert, daß der Thread mit der höchsten Priorität, immer der aktive Thread ist. D.h. wird ein Thread lauffähig und hat dieser eine höhere Priorität als der derzeit aktive Thread, dann wird der derzeit aktive Thread unterbrochen und in den Zustand lauffähig gesetzt. Der Thread mit der höheren Priorität wird aktiv gesetzt. Damit besteht in Java die Gefahr des Aushungerns (engl. starvation). Ein Thread niedriger Priorität läuft Gefahr niemals aktiv zu werden, wenn immer mindestens ein Thread mit einer höheren Priorität lauffähig ist. Existieren nur lauffähige Threads gleicher Priorität, dann wird nichtdeterministisch ein aktiver Thread gewählt. Auch bei notify() wird nichtdeterministisch ein Thread gewählt, der in den Zustand lauffähig übergeht. Daher können die Bildschirmausgaben in den Beispielen bei jedem Durchlauf variieren. Thread Wechsel Die virtuelle Maschine muß einen neuen Thread immer nur dann als aktiv auswählen wenn: ein Thread blockiert, oder ein Thread höherer Priorität, als der aktive Thread, lauffähig wird. Folglich: Ein notify() bedingt nicht notwendigerweise einen Threadwechsel. Eine Freigabe von Sperren bedingt nicht notwendigerweise einen Threadwechsel. 24 / 28

25 Die virtuelle Maschine darf, aber muß niemals, neue Threads aktiv setzen aufgrund von anderen Ereignissen. z.b. Unterbrechungen (engl. interrupts) oder Zeiteinheiten. Dies hängt von der jeweiligen Implementierung der VM ab. Java garantiert insbesondere nicht, daß alle lauffähigen Threads nacheinander für eine feste Zeiteinheit (Zeitscheiben) aktiviert werden. (engl. round robin strategy) Ohne eine explizite Angabe, haben alle erzeugten Threads die gleiche Priorität. Viele Unix Implementierungen wechseln die Threads nur dann, wenn sie müssen. Die Windows Implementierungen jedoch meistens auch zu anderen nicht genauer definierten Zeitpunkten. Folglich ist es durchaus möglich, daß bei den Beispielen die Threads nur nacheinander aktiv werden. Dies ist an sich nicht schlimm, da semantisch die gleiche Aufgabe erledigt wird. Dadurch können aber Synchronisationsfehler unentdeckt bleiben. Hintergrund Thread Java kennt neben normalen Benutzer Threads (engl.user threads) sogenannte Hintergrund Threads (engl. daemon threads). In Java endet ein Prozeß sobald alle Benutzer Threads zu Ende sind. Dann werden auch alle Hintergrund Threads automatisch beendet. Mit den Methoden void setdaemon( boolean on ) und boolean isdaemon() der Klasse Thread kann diese Eigenschaft eines Threads gesetzt und abgefragt werden. Beispielsweise gibt es in einem Java Prozeß immer ein Hintergrund Thread, der nicht mehr referenzierte Objekte aufräumt. (engl. garbage collection thread) 4.1 Zeitscheibenstrategie Um Abhilfe gegen die sequentielle Ausführung der Threads zu schaffen und das Verhalten der Testprogrammen besser zu illustrieren, können wir eine Zeitscheibenstrategie leicht implementieren. class RoundRobinScheduler extends Thread int timeslice; public RoundRobinScheduler( int timeslice ) this.timeslice = timeslice; setpriority( Thread.MAX_PRIORITY ); setdaemon(true); public void run() while( true ) try sleep( timeslice ); catch( Exception e ) 25 / 28

26 Jedesmal, wenn dieser Thread lauffähig wird, wird er aktiviert, da er die höchste Priorität hat. Anschließend blockiert er mit sleep() für einige Millisekunden. Ein anderer Thread kommt an die Reihe usw. Eine Zeitscheiben Strategie alleine garantiert nicht, daß alle Threads gleichmäßig an die Reihe kommen. Nehmen wir unsere Klasse Counter mit zwei Threads gleicher Priorität; folgender Ablauf ist denkbar und um so wahrscheinlicher, je mehr Threads das gleiche Counter Objekt verwenden: Beide Threads arbeiten in einer Schleife und der Haupt Thread hat den Zugriff auf den Zähler. Die Zeitscheibe ist vorbei, ein Threadwechsel wird erzwungen. Der zweite Thread wird aktiv, wird jedoch gleich blockiert, da der Haupt Thread den Zugriff hat. Der Haupt Thread wird wieder aktiv. Der Zugriff wird freigegeben. Der zweite Thread wird lauffähig aber nicht automatisch aktiv. Der Haupt Thread erhält wieder den Zugriff. Die Zeitscheibe ist vorbei, ein Threadwechsel wird erzwungen. Der zweiter Thread wird jetzt aktiv aber blockiert sofort wieder. usw... Nur wenn eine Unterbrechung stattfindet während der Haupt Thread den Zugriff freigegeben hat, dann kann der zweite Thread an die Reihe kommen und den Zugriff erhalten. Erst eine Warteschlange bei der Vergabe des Zugriffs würde Abhilfe schaffen. D.h. Die Wartenden reihen sich ein. Nur der Erste in der Schlange kann den Zugriff nach einer Freigabe erhalten. 4.2 Sperre mit Warteschlange Im folgenden implementieren wir eine Sperr, die eine Warteschlange beinhaltet mit den Standard Java Synchronisationsmechanismen. Ein Thread soll warten, bis er als erster in der Warteschlange steht. Die Schnittstelle lautet: interface QueuedLock aquire() release(); Damit läßt sich synchronized( o ) / 28

27 durch o.lock.aquire();... o.lock.release(); ersetzen. Wobei lock ein öffentliches Attribut von o ist. Das Attribut lock ist dann vom Typ QueuedLock. Achtung: Eine Schachtelung von o.lock.aquire()...o.lock.release(); Bereiche, ohne sich selbst aus zu sperren, wie bei synchronized, sollte möglich sein. Mit dem Standard Mechanismus synchronized muß der Thread immer warten, falls er den Zugriff nicht enthalten kann. Manchmal gäbe es aber die Möglichkeit eine Alternative auszuführen. Erweitern Sie QueuedLock um eine Methode boolean tryaquire(). 5 Anmerkungen Sicherheit Threads werden von der virtuellen Maschine hierarchisch gruppiert. Zugang zu dieser Struktur bietet die Klasse ThreadGroup. Alle Applets werden in einem Prozeß ausgeführt. Jedes Applet hat einen eigenen ThreadGroup. Applets sollten nicht die Threads von anderen Applets beeinflussen können, es sei denn, es wird explizit erlaubt. Daher werden Aufrufe für Threads aus einer anderen ThreadGroup als der eigenen geprüft. Der Sicherheitsmanager, d.h. die Instanz der Klasse SecurityManager, wird jedesmal gefragt, ob der Aufruf erlaubt ist. Richtlinien Die Programmierung für mehrere Threads ist nicht trivial. Nachträglich sequentiellen Code für mehrere Threads tauglich (engl. thread safe) zu machen, liefert nur selten befriedigende Ergebnisse. Vor allem die Strategie der Sperrenvergabe ist vorher zu überlegen: Die Sperren Granularität sollte so grob wie möglich gewählt werden. Dies schränkt zwar die Nebenläufigkeit ein, verringert jedoch die Anzahl der Konfliktsituationen. Solange der Ablauf fair ist entsteht auch ein sinnvolles Ergebnis. Es ist immer abzuwägen, ob nur das Endergebnis zählt, oder ob auch Zwischenergebnisse wichtig sind. Wenn nur das Endergebnis zählt, ist eine geringere Nebenläufigkeit tragbar. Da die meisten virtuellen Maschinen bisher nur einen Prozessor unterstützen, verlangsamt ein häufiger Wechsel der Threads die Berechnung eher. Nur wenn Zwischenergebnisse gebraucht werden, sollte die Granularität verfeinert werden. Die Anzahl der gemeinsamen Variablen sollte so klein wie möglich bleiben. Z.B. bei der Druckaufbereitung in einem eigenem Thread ist es erheblich einfacher den gesamten Text im Speicher zu kopieren und dann zu formatieren, als die Zugriffe auf dem Text zu synchronisieren. 27 / 28

28 Fehler Ein unbedachter Einsatz von Nebenläufigkeit in Java führt auf eine tückische Fehlerquelle. Fehler tauchen in bereits getesteten Programmen unvermittelt, je nach Javaimplementierung, Rechner, Ablaufgeschwindigkeit, Betriebssystem usw. auf. Die Fehlersuche ist aufwendig. die Fehler sind schwer reproduzierbar. Eine Suche mit einem Debugger kann den Ablauf stark beeinflussen. Dadurch können Fehler "verschwinden". Auch die Ausgabe von Meldungen kann die Synchronisation beeinflussen. Wiederverwendung Synchronisation bedeutet ein erhebliches mehr an Code bzw. Code Änderungen. Synchronisations Code legt eine Verwendungsart fest. Z.B. kann in einer Methode gewartet werden, bis eine Bedingung eintritt oder einfach eine Fehlermeldung zurückgeben werden. Beide Verhaltensweisen können je nach Kontext sinnvoll sein. Es kann sinnvoll sein, den Synchronisations Code und den funktionalen Kern zu trennen. Der Synchronisations Code wird dann in eine Adapter Klasse verlagert, die den funktionalen Kern aufruft. Den funktionalen Kern kann man dann auch in einem sequentiellen Kontext einsetzen, wo eine Synchronisation nicht erwünscht ist. Denn Synchronisations Code beansprucht auch erhebliche Rechenzeit. 6 Literatur [Bro98] M. Broy, Informatik Eine grundlegende Einführung Band 2, Springer Verlag, 1998 [Dou97] Doug Lea, Concurrent Programming in Java, Design Principles and Patterns, Addison Wesley, 1997 [LiF97] Tim Lindholm & Frank Yellin, The Java Virtual Maschine Specification, Addision Wesley, 1997 [ScH97] Scott Oaks & Henry Wong, Java Threads, O Reilly & Associates, / 28

5. Threads, Serverprozesse und Benachrichtigungen

5. Threads, Serverprozesse und Benachrichtigungen 5. Threads, Serverprozesse und Benachrichtigungen Threads allgemein Threads in Android: Handler und Messages Services: Local, Remote, Binding Benachrichtigungen Entwicklung mobiler Anwendungen Europäische

Mehr

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

Zur Erinnerung: Threads. Threadverwaltung. Threads: Prioritäten. Beispiel Flugbuchungsprogramm. Nichtdeterminismus Zur Erinnerung: Threads Programmierung (fortgeschrittene Konzepte) Threads, Monitore, Semaphore und speisende en Wolf-Ulrich Raffel (uli@wuraffel.de) Möglichkeiten, Threads zu definieren Bildung einer

Mehr

Synchronisation in Java. Invisible Web

Synchronisation in Java. Invisible Web Synchronisation in Java Studienprojekt Invisible Web Tang Zhihong Synchronisation in Java Synchronisationsproblem Monitore Wait und notify PipedInputStream und PipedOutputStream Synchronisation von Collections

Mehr

2.2 Prozesse in Java

2.2 Prozesse in Java 2.2 Prozesse in Java! Java sieht kein Schlüsselwort für Prozesse vor, sondern bestimmte Klassen und Schnittstellen. Mit anderen Worten: der Prozessbegriff wird mit Mitteln der Objektorientierung eingeführt.

Mehr

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

Betriebssysteme. Wintersemester 2015. Kapitel 2 Prozess und Threads. Patrick Kendzo ppkendzo@gmail.com Betriebssysteme Wintersemester 2015 Kapitel 2 Prozess und Threads Patrick Kendzo ppkendzo@gmail.com Programm Inhalt Einleitung Prozesse und Threads Speicherverwaltung Eingabe und Ausgabe Dateisysteme Zusammenfassung

Mehr

Einführung in die Programmierung Blockkurs Java

Einführung in die Programmierung Blockkurs Java Michael Bader 8. 12. April 2002 Freitag Inhaltsübersicht Exceptions und Errors Ausnahmebehandlung: try/catch/finally Threads Zugriffskontrolle bei gemeinsamen Variablen: synchronized, wait(), notify()

Mehr

Probeklausur: Programmierung WS04/05

Probeklausur: Programmierung WS04/05 Probeklausur: Programmierung WS04/05 Name: Hinweise zur Bearbeitung Nimm Dir für diese Klausur ausreichend Zeit, und sorge dafür, dass Du nicht gestört wirst. Die Klausur ist für 90 Minuten angesetzt,

Mehr

Schritt 1 - Ein Spielfeld

Schritt 1 - Ein Spielfeld Schritt 1 - Ein Spielfeld Wir beginnen mit zwei einfachen Java-Klassen, dem eigentlichen Spielfeld und dem Applet zum Anzeigen des Spielfeldes (und später der Buttons und der anderen Bedienelemente). Hier

Mehr

Eine Klasse beschreibt Objekte mit gleichen Attributen und Methoden.

Eine Klasse beschreibt Objekte mit gleichen Attributen und Methoden. Grundwissen Informatik Objekt Attribut Methoden Als Objekte bezeichnet man alle Gegenstände, Dinge, Lebewesen, Begriffe oder Strukturen unserer Welt ( Autos, Räume, Bakterien, Lehrer, Schüler, Kunden,

Mehr

Monitore. Klicken bearbeiten

Monitore. Klicken bearbeiten Sascha Kretzschmann Institut für Informatik Monitore Formatvorlage und deren Umsetzung des Untertitelmasters durch Klicken bearbeiten Inhalt 1. Monitore und Concurrent Pascal 1.1 Warum Monitore? 1.2 Monitordefinition

Mehr

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

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 14/15. Kapitel 11. Fehler und Ausnahmen 1 Kapitel 11 Fehler und Ausnahmen Fehler und Ausnahmen 1 Ziele Fehlerquellen in Programmen und bei der Programmausführung verstehen Das Java-Konzept der Ausnahmen als Objekte kennenlernen Ausnahmen auslösen

Mehr

LeJOS: Mindstorms in Java programmieren

LeJOS: Mindstorms in Java programmieren LeJOS: Mindstorms in Java programmieren Alexander Koller Softwareprojekt "Sprechende Roboter" 30. April 2004 Überblick Warum Java? Was ist LeJOS? Motoren steuern Auf Sensoreingaben reagieren Wie geht's

Mehr

Programmieren I. Kontrollstrukturen. Heusch 8 Ratz 4.5. www.kit.edu. Institut für Angewandte Informatik

Programmieren I. Kontrollstrukturen. Heusch 8 Ratz 4.5. www.kit.edu. Institut für Angewandte Informatik Programmieren I Kontrollstrukturen Heusch 8 Ratz 4.5 KIT Universität des Landes Baden-Württemberg und nationales Großforschungszentrum in der Helmholtz-Gemeinschaft www.kit.edu Arten von Kontrollstrukturen

Mehr

Musterlösungen zur Klausur Informatik 3

Musterlösungen zur Klausur Informatik 3 Musterlösungen zur Klausur Informatik 3 Justus-Liebig-Universität Gießen Wintersemester 2003/2004 Aufgabe 1 (6 Punkte) Man kreuze bei den folgenden Deklarationen und Definitionen jeweils an, ob sie aus

Mehr

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

Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden. Einfache Ein- und Ausgabe mit Java 1. Hallo-Welt! Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden. /** Die Klasse hello sendet einen

Mehr

Objektorientierte Programmierung

Objektorientierte Programmierung Objektorientierte Programmierung 1 Geschichte Dahl, Nygaard: Simula 67 (Algol 60 + Objektorientierung) Kay et al.: Smalltalk (erste rein-objektorientierte Sprache) Object Pascal, Objective C, C++ (wiederum

Mehr

Kapitel 6. Vererbung

Kapitel 6. Vererbung 1 Kapitel 6 2 Ziele Das sprinzip der objektorientierten Programmierung verstehen Und in Java umsetzen können Insbesondere folgende Begriffe verstehen und anwenden können: Ober/Unterklassen Subtyping Überschreiben

Mehr

Parallele Programmierung in Java

Parallele Programmierung in Java PPJ-1 Parallele Programmierung in Java Prof. Dr. Uwe Kastens Sommersemester 2000 Vorlesung Parallele Programmierung in Java SS 2000 / Folie 01 PPJ-2 Ziele und Durchführung Die Studierenden sollen grundlegende

Mehr

Computeranwendung und Programmierung (CuP)

Computeranwendung und Programmierung (CuP) Computeranwendung und Programmierung (CuP) VO: Peter Auer (Informationstechnologie) UE: Norbert Seifter (Angewandet Mathematik) Organisatorisches (Vorlesung) Vorlesungszeiten Montag 11:15 12:45 Freitag

Mehr

II.1.1. Erste Schritte - 1 -

II.1.1. Erste Schritte - 1 - ! 1. Grundelemente der Programmierung! 2. Objekte, Klassen und Methoden! 3. Rekursion und dynamische Datenstrukturen! 4. Erweiterung von Klassen und fortgeschrittene Konzepte II.1.1. Erste Schritte - 1

Mehr

Kapitel 6. Vererbung

Kapitel 6. Vererbung 1 Kapitel 6 2 Ziele Das sprinzip der objektorientierten Programmierung verstehen Und in Java umsetzen können Insbesondere folgende Begriffe verstehen und anwenden können: Ober/Unterklassen Subtyping Überschreiben

Mehr

1 Polymorphie (Vielgestaltigkeit)

1 Polymorphie (Vielgestaltigkeit) 1 Polymorphie (Vielgestaltigkeit) Problem: Unsere Datenstrukturen List, Stack und Queue können einzig und allein int-werte aufnehmen. Wollen wir String-Objekte, andere Arten von Zahlen oder andere Objekttypen

Mehr

5.4 Klassen und Objekte

5.4 Klassen und Objekte 5.4 Klassen und Objekte Zusammenfassung: Projekt Figuren und Zeichner Figuren stellt Basisklassen für geometrische Figuren zur Verfügung Zeichner bietet eine übergeordnete Klasse Zeichner, welche die Dienstleistungen

Mehr

Kapitel 6. Vererbung

Kapitel 6. Vererbung Kapitel 6 Vererbung Vererbung 1 Ziele Das Vererbungsprinzip der objektorientierten Programmierung verstehen Und in Java umsetzen können Insbesondere folgende Begriffe verstehen und anwenden können: Ober/Unterklassen

Mehr

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

Beispiel: Methode mit einem Fehler. Diese Methode wird problematisch, wenn von außen eine Dauer von 0 Sekunden angegeben wird, etwa im Aufruf 16 Exceptions Zur Behandlung unerwarteter Situationen bietet Java Unterstützung in Form von Exceptions oder Ausnahmen. Den Sinn von Exceptions können wir Ihnen an einem kleinen Beispiel klarmachen. Nehmen

Mehr

Java für Computerlinguisten

Java für Computerlinguisten Java für Computerlinguisten 2. Objektorientierte Programmierung Christian Scheible Institut für Maschinelle Sprachverarbeitung 28. Juli 2009 Christian Scheible Java für Computerlinguisten 28. Juli 2009

Mehr

Verteilte Systeme CS5001

Verteilte Systeme CS5001 Verteilte Systeme CS5001 Th. Letschert TH Mittelhessen Gießen University of Applied Sciences Client-Server-Anwendungen: Vom passiven (shared state) Monitor zum aktiven Monitor Monitor (Hoare, Brinch-Hansen,

Mehr

Java-Programmierung. Remote Method Invocation - RMI

Java-Programmierung. Remote Method Invocation - RMI Java-Programmierung Remote Method Invocation - RMI Entwicklungsmethoden Sockets Entwurf verteilter Anwendungen ist relativ aufwändig, da zunächst ein Kommunikationsprotokoll entwickelt werden muss aufwändig

Mehr

Universität Karlsruhe (TH)

Universität Karlsruhe (TH) Universität Karlsruhe (TH) Forschungsuniversität gegründet 1825 Cluster-Praktikum Sommersemester 2007 Transparent Replizierte Objekte in JavaParty Institut für Programmstrukturen und Datenorganisation

Mehr

Betriebssystembau (BSB)

Betriebssystembau (BSB) Betriebssystembau (BSB) 6. Übung http://ess.cs.tu-.de/de/teaching/ws2013/bsb/ Olaf Spinczyk olaf.spinczyk@tu-.de http://ess.cs.tu-.de/~os AG Eingebettete System Informatik 12, TU Dortmund Agenda Vorstellung

Mehr

Klausurvorbereitung VS1 (Prof. Brecht) (B0rg Edition)

Klausurvorbereitung VS1 (Prof. Brecht) (B0rg Edition) Ein Prozess kann unmittelbar vom Zustand 1. Running in den Zustand Ready 2. Running in den Zustand Blocked 3. Ready in den Zustand Running Klausurvorbereitung VS1 (Prof. Brecht) (B0rg Edition) Der Adressraum

Mehr

Systeme 1. Kapitel 6. Nebenläufigkeit und wechselseitiger Ausschluss

Systeme 1. Kapitel 6. Nebenläufigkeit und wechselseitiger Ausschluss Systeme 1 Kapitel 6 Nebenläufigkeit und wechselseitiger Ausschluss Threads Die Adressräume verschiedener Prozesse sind getrennt und geschützt gegen den Zugriff anderer Prozesse. Threads sind leichtgewichtige

Mehr

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

VS4 Slide 1. Verteilte Systeme. Vorlesung 4 vom 29.04.2004 Dr. Sebastian Iwanowski FH Wedel VS4 Slide 1 Verteilte Systeme Vorlesung 4 vom 29.04.2004 Dr. Sebastian Iwanowski FH Wedel Inhaltsverzeichnis für die Vorlesung Zur Motivation: 4 Beispiele aus der Praxis Allgemeine Anforderungen an Verteilte

Mehr

Softwarelösungen: Versuch 4

Softwarelösungen: Versuch 4 Softwarelösungen: Versuch 4 Nichtstun in Schleife wird ersetzt durch zeitweilige Zurücknahme der Anforderung, um es anderen Prozessen zu erlauben, die Ressource zu belegen: /* Prozess 0 */ wiederhole flag[0]

Mehr

J.5 Die Java Virtual Machine

J.5 Die Java Virtual Machine Java Virtual Machine Die Java Virtual Machine 22 Prof. Dr. Rainer Manthey Informatik II Java-Compiler und Java Virtual Machine Quellcode-Datei class C... javac D.java Java-Compiler - Dateien class class

Mehr

Klassenbeziehungen & Vererbung

Klassenbeziehungen & Vererbung Klassenbeziehungen & Vererbung VL Objektorientierte Programmierung Raimund Kirner teilweise nach Folien von Franz Puntigam, TU Wien Überblick Arten von Klassenbeziehungen Untertypen versus Vererbung in

Mehr

Vererbung & Schnittstellen in C#

Vererbung & Schnittstellen in C# Vererbung & Schnittstellen in C# Inhaltsübersicht - Vorüberlegung - Vererbung - Schnittstellenklassen - Zusammenfassung 1 Vorüberlegung Wozu benötigt man Vererbung überhaubt? 1.Um Zeit zu sparen! Verwendung

Mehr

Nebenläufige Programmierung I

Nebenläufige Programmierung I Nebenläufige Programmierung I Martin Wirsing in Zusammenarbeit mit Moritz Hammer und Axel Rauschmayer SS06 2 Ziele Grundlegende Begriffe der nebenläufigen Programmierung verstehen lernen Nebenläufige Programme

Mehr

Grundlagen Programmierung

Grundlagen Programmierung 13. Aufgabe (13 Punkte) Schreiben Sie eine neue Klasse Zahlenanalyse, mit der Integer-Objekte genauer betrachtet werden können. Bei den zu entwickelnden Methoden kann es immer sinnvoll sein, sich den Ablauf

Mehr

Grundlagen der Informatik Ausnahmebehandlung & Threads

Grundlagen der Informatik Ausnahmebehandlung & Threads Grundlagen der Informatik Ausnahmebehandlung & Threads Prof. Dr. Bernhard Schiefer (basierend auf Unterlagen von Prof. Dr. Duque-Antón) bernhard.schiefer@fh-kl.de http://www.fh-kl.de/~schiefer Inhalt Ausnahmebehandlung

Mehr

Aufgabe 1. »Programmieren«, WS 2006/2007. Nino Simunic M.A.

Aufgabe 1. »Programmieren«, WS 2006/2007. Nino Simunic M.A. »Programmieren«, WS 006/007 Nino Simunic (nino.simunic@uni-due.de) Übungsblatt 4 Aufgabe 1 OOP In dieser Aufgabe sollen Sie Autos als Klasse Car modellieren. Die Eigenschaften auf attributiver Ebene sind:

Mehr

Java Kurs für Anfänger Einheit 5 Methoden

Java Kurs für Anfänger Einheit 5 Methoden Java Kurs für Anfänger Einheit 5 Methoden Ludwig-Maximilians-Universität München (Institut für Informatik: Programmierung und Softwaretechnik von Prof.Wirsing) 22. Juni 2009 Inhaltsverzeichnis Methoden

Mehr

Verbessertes Konzept: Monitore

Verbessertes Konzept: Monitore Verbessertes Konzept: Monitore Ein Nachteil von Semaphoren ist die Notwendigkeit zur expliziten Anforderung P und Freigabe V des kritischen Bereiches durch den Programmierer Vergißt der Entwickler z.b.

Mehr

Zusammenfassung Modul 223

Zusammenfassung Modul 223 Zusammenfassung Modul 223 von Christian Roth Powered by Schuschu Bison Schweiz AG, Surentalstrasse 10, CH-6210 Sursee, www.bison-group.com Inhaltsverzeichnis 1 Entwurfmuster... 3 1.1 Singleton... 3 1.1.1

Mehr

Abschnitt 9: Schnittstellen: Interfaces

Abschnitt 9: Schnittstellen: Interfaces Abschnitt 9: Schnittstellen: Interfaces 9. Schnittstellen: Interfaces 9.1 Die Idee der Schnittstellen 9.2 Schnittstellen in Java 9.3 Marker-Interfaces 9.4 Interfaces und Hilfsklassen 9.5 Zusammenfassung

Mehr

Folge 18 - Vererbung

Folge 18 - Vererbung Workshop Folge 18 - Vererbung 18.1 Ein einfacher Fall der Vererbung Schritt 1 - Vorbereitungen Besorgen Sie sich - vielleicht aus einer der Übungen der Folge 17 - ein fertiges und lauffähiges Listenprojekt,

Mehr

3 Objektorientierte Konzepte in Java

3 Objektorientierte Konzepte in Java 3 Objektorientierte Konzepte in Java 3.1 Klassendeklarationen Fragen an die Klassendeklaration: Wie heißt die Klasse? Wer darf auf die Klasse und ihre Attribute/Methoden zugreifen? Ist die Klasse eine

Mehr

Das Monitorkonzept Brinch-Hansen

Das Monitorkonzept Brinch-Hansen Das Monitorkonzept (nach Hoare/Brinch Brinch-Hansen 1974) Nur ein Prozess bzw. Thread kann zu einem bestimmten Zeitpunkt im Monitor aktiv sein => gegenseitiger Ausschluss, mutual exclusion. Geschützte

Mehr

Universität Augsburg, Institut für Informatik Sommersemester 2005 Prof. Dr. Werner Kießling 15. Oktober 2005 Dr. Alfons Huhn, Timotheus Preisinger

Universität Augsburg, Institut für Informatik Sommersemester 2005 Prof. Dr. Werner Kießling 15. Oktober 2005 Dr. Alfons Huhn, Timotheus Preisinger Universität Augsburg, Institut für Informatik Sommersemester 2005 Prof. Dr. Werner Kießling 15. Oktober 2005 Dr. Alfons Huhn, Timotheus Preisinger Informatik II Hinweise: Die Bearbeitungszeit beträgt 90

Mehr

3 Objektorientierte Konzepte in Java

3 Objektorientierte Konzepte in Java 3 Objektorientierte Konzepte in Java Bisherige Beobachtungen zu Objekten: werden in Klassen zusammengefasst besitzen Eigenschaften und Verhalten verbergen private Informationen werden geboren, leben und

Mehr

Algorithmische Kernsprache. Zuweisung, einfache und bedingte Anweisung, Blöcke, Schleifen, return, debugging.

Algorithmische Kernsprache. Zuweisung, einfache und bedingte Anweisung, Blöcke, Schleifen, return, debugging. Algorithmische Kernsprache Zuweisung, einfache und bedingte Anweisung, Blöcke, Schleifen, return, debugging. Ausdrücke Anweisungen Ausdrücke bezeichnen einen Wert Kontext stellt Werte von Variablen Werte

Mehr

Variablen manipulieren per JDI

Variablen manipulieren per JDI Variablen manipulieren per JDI Zusammenfassung Jede moderne Java IDE verfügt über eine mächtige und dennoch meist einfach zu bedienende Benutzeroberfläche die das finden von Fehlern in lokalen oder entfernt

Mehr

5. Tutorium zu Programmieren

5. Tutorium zu Programmieren 5. Tutorium zu Programmieren Dennis Ewert Gruppe 6 Universität Karlsruhe Institut für Programmstrukturen und Datenorganisation (IPD) Lehrstuhl Programmierparadigmen WS 2008/2009 c 2008 by IPD Snelting

Mehr

5.5.8 Öffentliche und private Eigenschaften

5.5.8 Öffentliche und private Eigenschaften 5.5.8 Öffentliche und private Eigenschaften Schnittstellen vs. Implementierungen: Schnittstelle einer Klasse beschreibt, was eine Klasse leistet und wie sie benutzt werden kann, ohne dass ihre Implementierung

Mehr

Java Generics & Collections

Java Generics & Collections Java Praktikum Effizientes Programmieren (Sommersemester 2015) Dennis Reuling Agenda 1 2 3 1 / 30 Praktikum Effizientes Programmieren (Sommersemester 2015) Java Subtyping Teil 1 2 / 30 Praktikum Effizientes

Mehr

Ein erstes Java-Programm

Ein erstes Java-Programm Ein erstes Java-Programm public class Rechnung { public static void main (String [] arguments) { int x, y; x = 10; y = -1 + 23 * 33 + 3 * 7 * (5 + 6); System.out.print ("Das Resultat ist "); System.out.println

Mehr

Einführung Datentypen Verzweigung Schleifen Funktionen Dynamische Datenstrukturen. Java Crashkurs. Kim-Manuel Klein (kmk@informatik.uni-kiel.

Einführung Datentypen Verzweigung Schleifen Funktionen Dynamische Datenstrukturen. Java Crashkurs. Kim-Manuel Klein (kmk@informatik.uni-kiel. Java Crashkurs Kim-Manuel Klein (kmk@informatik.uni-kiel.de) May 7, 2015 Quellen und Editoren Internet Tutorial: z.b. http://www.java-tutorial.org Editoren Normaler Texteditor (Gedit, Scite oder ähnliche)

Mehr

7. Objektorientierte Softwareentwicklung/3. Informatik II für Verkehrsingenieure

7. Objektorientierte Softwareentwicklung/3. Informatik II für Verkehrsingenieure 7. Objektorientierte Softwareentwicklung/3 Informatik II für Verkehrsingenieure Überblick FOLGENDE BEGRIFFE/PRINZIPIEN SOLLTEN BEKANNT SEIN Objekte Klasse Attribute Fähigkeiten ZIEL DER HEUTIGEN LEHRVERANSTALTUNG

Mehr

Programmieren in Java

Programmieren in Java Programmieren in Java objektorientierte Programmierung 2 2 Zusammenhang Klasse-Datei In jeder *.java Datei kann es genau eine public-klasse geben wobei Klassen- und Dateiname übereinstimmen. Es können

Mehr

IT in der Arztpraxis Technisches Handbuch zum Kodierassistenten

IT in der Arztpraxis Technisches Handbuch zum Kodierassistenten Technisches Handbuch zum Kodierassistenten [KBV_ITA_AHEX_Handbuch_Kodierassistent] Dezernat 6 Informationstechnik, Telematik und Telemedizin 10623 Berlin, Herbert-Lewin-Platz 2 Kassenärztliche Bundesvereinigung

Mehr

Dr. Monika Meiler. Inhalt

Dr. Monika Meiler. Inhalt Inhalt 5 Referenzdatentypen - Felder... 5-2 5.1 Eindimensionale Felder - Vektoren... 5-3 5.1.1 Vereinbarung... 5-3 5.1.2 Referenzen sind keine Felder... 5-4 5.1.3 Kopieren eindimensionaler Felder... 5-6

Mehr

Distributed Computing Group

Distributed Computing Group JAVA TUTORIAL Distributed Computing Group Vernetzte Systeme - SS 06 Übersicht Warum Java? Interoperabilität grosse und gut dokumentierte Library weit verbreitet Syntax sehr nahe an C Erfahrung: Java wird

Mehr

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

Allgemein: Klassen testbar machen. 5. Mocking. Mocks programmieren. Zusammenspiel von Klassen testen 5. Mocking Allgemein: Klassen testbar machen Wie werden Klassen testbar Entwicklung von Mocks mit der Hand Einführung in JMock Spezifikation von Mocks mit JMock Wann ist Mocking-Werkzeug sinnvoll Literatur:

Mehr

Gliederung. Tutorium zur Vorlesung. Gliederung. Gliederung. 1. Gliederung der Informatik. 1. Gliederung der Informatik. 1. Gliederung der Informatik

Gliederung. Tutorium zur Vorlesung. Gliederung. Gliederung. 1. Gliederung der Informatik. 1. Gliederung der Informatik. 1. Gliederung der Informatik Informatik I WS 2012/13 Tutorium zur Vorlesung 1. Alexander Zietlow zietlow@informatik.uni-tuebingen.de Wilhelm-Schickard-Institut für Informatik Eberhard Karls Universität Tübingen 11.02.2013 1. 2. 1.

Mehr

Innere Klassen in Java

Innere Klassen in Java Innere Klassen in Java SS 2012 Prof. Dr. Margarita Esponda Innere Klassen Klassen- oder Interfacedefinitionen können zur besseren Strukturierung von Programmen verschachtelt werden Eine "Inner Class" wird

Mehr

Technische Informatik II

Technische Informatik II Institut für Technische Informatik und Kommunikationsnetze Technische Informatik II Übung 1: Prozesse und Threads Aufgabe 1: Prozesse und Threads a) Wie verhält sich eine Applikation die aus mehreren Prozessen

Mehr

Grundlagen zur nebenläufigen Programmierung in Java

Grundlagen zur nebenläufigen Programmierung in Java Grundlagen zur nebenläufigen Programmierung in Java Karlsruher Entwicklertag 2013 5. Juni 2013 Referent: Christian Kumpe Inhalt des Vortrags Was zeigt dieser Vortrag? Ein einfaches Beispiel mit allerlei

Mehr

Inhalt. Max Lini. ax. inie. Einleitung... VII

Inhalt. Max Lini. ax. inie. Einleitung... VII rst Inhalt Einleitung....................................................... VII 1 Schöne neue Welt: Objektorientierte Programmierung in PHP 5.............. 1 Klassen, Interfaces und Objekte...................................

Mehr

Primitive Datentypen

Primitive Datentypen Primitive Datentypen 2 Arten von Datentypen: primitive Datentypen (heute) Objekte (später) Java ist streng typisiert, d.h. für jede Variable muß angegeben werden was für eine Art von Wert sie aufnimmt.

Mehr

2A Basistechniken: Weitere Aufgaben

2A Basistechniken: Weitere Aufgaben 2A Basistechniken: Weitere Aufgaben 2A.3 Programmierung unter UNIX/Linux 1. Gegeben sind einige Ausschnitte von C-Programmen, die unter UNIX/Linux ausgeführt werden sollen. Beantworten Sie die zugehörigen

Mehr

Autor: Michael Spahn Version: 1.0 1/10 Vertraulichkeit: öffentlich Status: Final Metaways Infosystems GmbH

Autor: Michael Spahn Version: 1.0 1/10 Vertraulichkeit: öffentlich Status: Final Metaways Infosystems GmbH Java Einleitung - Handout Kurzbeschreibung: Eine kleine Einführung in die Programmierung mit Java. Dokument: Autor: Michael Spahn Version 1.0 Status: Final Datum: 23.10.2012 Vertraulichkeit: öffentlich

Mehr

6. Tutorium zu Softwaretechnik I

6. Tutorium zu Softwaretechnik I 6. Tutorium zu Softwaretechnik I Parallelität und Testen Michael Hoff 01.07.2014 INSTITUT FÜR PROGRAMMSTRUKTUREN UND DATENORGANISATION KIT Universität des Landes Baden-Württemberg und nationales Forschungszentrum

Mehr

620.900 Propädeutikum zur Programmierung

620.900 Propädeutikum zur Programmierung 620.900 Propädeutikum zur Programmierung Andreas Bollin Institute für Informatik Systeme Universität Klagenfurt Andreas.Bollin@uni-klu.ac.at Tel: 0463 / 2700-3516 Arrays Wiederholung (1/5) Array = GEORDNETE

Mehr

Java RMI Remote Method Invocation

Java RMI Remote Method Invocation Java RMI Remote Method Invocation Ziel: Aufruf von Instanzmethoden entfernter Objekte basierend auf Java. Paket: java.rmi und Unterpakete Topologie: RMI Registry RMI Server RMI Client Der Server registriert

Mehr

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

1. Der Einstieg in Java. Was heißt Programmieren? 1. Der Einstieg in Java Lernziele: Am Ende dieses Kapitels sollen Sie wissen, aus welchen Bestandteilen ein Java-Programm besteht, Java-Programme übersetzen und ausführen können, Möglichkeiten der Kommentierung

Mehr

1. Grundlegende Konzepte in Java (6 Punkte)

1. Grundlegende Konzepte in Java (6 Punkte) 1. Grundlegende Konzepte in Java (6 Punkte) a) Welches der folgenden Literale ist korrekt und wenn ja, von welchem Typ ist es? "true" nicht korrekt X korrekt vom Typ String 'true' X nicht korrekt korrekt

Mehr

13 OOP MIT DELPHI. Records und Klassen Ein Vergleich

13 OOP MIT DELPHI. Records und Klassen Ein Vergleich 13 OOP MIT DELPHI Delphi war früher "Object Pascal". Dieser Name impliziert eine Funktionalität, welche in der Welt der Programmierung nicht mehr wegzudenken ist: die objektorientierte Programmierung,

Mehr

Datenbankanwendungsprogrammierung Crashkurs Java

Datenbankanwendungsprogrammierung Crashkurs Java Datenbankanwendungsprogrammierung Crashkurs Java Denny Priebe Datenbankanwendungsprogrammierung p. Unterschiede zu C, C++ typedefs, Präprozessor Strukturen, Unions globale Funktionen Mehrfachvererbung

Mehr

Programmieren I. Prinzipieller Ablauf. Eigenschaften von JAVA. Source-Code Javac Bytecode. Java Virtual Machine (Java, Browser, Appletviewer)

Programmieren I. Prinzipieller Ablauf. Eigenschaften von JAVA. Source-Code Javac Bytecode. Java Virtual Machine (Java, Browser, Appletviewer) Programmieren I Grundlagen von JAVA Dr. Klaus Höppner Hello World in JAVA Hochschule Darmstadt WS 2007/2008 Elementare Datentypen 1 / 17 2 / 17 Eigenschaften von JAVA Prinzipieller Ablauf Plattform-und

Mehr

Java Einführung Programmcode

Java Einführung Programmcode Java Einführung Programmcode Inhalt dieser Einheit Programmelemente Der erste Programmcode Die Entwicklungsumgebung: Sun's Java Software Development Kit (SDK) Vom Code zum Ausführen des Programms 2 Wiederholung:

Mehr

Große Übung Praktische Informatik 1

Große Übung Praktische Informatik 1 Große Übung Praktische Informatik 1 2005-12-08 fuessler@informatik.uni-mannheim.de http://www.informatik.uni-mannheim.de/pi4/people/fuessler 1: Announcements / Orga Weihnachtsklausur zählt als Übungsblatt,

Mehr

Methoden. von Objekten definiert werden, Methoden,, Zugriffsmethoden und Read-Only

Methoden. von Objekten definiert werden, Methoden,, Zugriffsmethoden und Read-Only Methoden Wie Konstruktoren und Destruktoren zum Auf- und Abbau von Objekten definiert werden, Wie inline-methoden Methoden,, Zugriffsmethoden und Read-Only Only- Methoden einzusetzen sind, Der this-pointer

Mehr

Datentechnik. => Das Rechenergebnis ist nur dann sinnvoll, wenn es rechtzeitig vorliegt. Die Zeit muß daher beim Programmdesign berücksichtigt werden.

Datentechnik. => Das Rechenergebnis ist nur dann sinnvoll, wenn es rechtzeitig vorliegt. Die Zeit muß daher beim Programmdesign berücksichtigt werden. 5. Steuerung technischer Prozesse 5.1 Echtzeit (real time) Im Gegensatz zu Aufgabenstellungen aus der Büroumgebung, wo der Anwender mehr oder weniger geduldig wartet, bis der Computer ein Ergebnis liefert

Mehr

Musterlösung zur Vorlesung Modellbasierte Softwareentwicklung Wintersemester 2014/2015 Übungsblatt 9

Musterlösung zur Vorlesung Modellbasierte Softwareentwicklung Wintersemester 2014/2015 Übungsblatt 9 Prof. Dr. Wilhelm Schäfer Paderborn, 15. Dezember 2014 Christian Brenner Tristan Wittgen Musterlösung zur Vorlesung Modellbasierte Softwareentwicklung Wintersemester 2014/2015 Übungsblatt 9 Aufgabe 1 Codegenerierung

Mehr

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

Einfache Arrays. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung Annabelle Klarl Zentralübung zur Vorlesung Einführung in die Informatik: http://www.pst.ifi.lmu.de/lehre/wise-13-14/infoeinf WS13/14 Action required now 1. Smartphone: installiere die App "socrative student"

Mehr

Javakurs für Anfänger

Javakurs für Anfänger Javakurs für Anfänger Einheit 02: Klassen & Objekte Lorenz Schauer Lehrstuhl für Mobile und Verteilte Systeme Heutige Agenda 1. Teil: Klassen Grundstruktur einer Java-Klasse Eigenschaften (Attribute) Variablen

Mehr

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

Problemstellung. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 24: Reflection 1. IDE und automatische Tests. Universität Osnabrück 1 Problemstellung 3 - Objektorientierte Programmierung in Java Vorlesung 24: Reflection 1 SS 2006 Prof. Dr. Frank M. Thiesing, FH Osnabrück Um ein Objekt anzulegen, eine seiner Methoden

Mehr

Kapitel 4. Monitore und wechselseitiger Ausschluss

Kapitel 4. Monitore und wechselseitiger Ausschluss Seite 1 Kapitel 4 Monitore und wechselseitiger Ausschluss Prof. Dr. Rolf Hennicker 28.05.2015 4.1 Interferenzen Seite 2 Parallel ablaufende Prozesse können sich gegenseitig (störend) beeinflussen. Beispiel

Mehr

Java 7. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Dezember 2011 JAV7

Java 7. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Dezember 2011 JAV7 Java 7 Elmar Fuchs Grundlagen Programmierung 1. Ausgabe, Dezember 2011 JAV7 5 Java 7 - Grundlagen Programmierung 5 Kontrollstrukturen In diesem Kapitel erfahren Sie wie Sie die Ausführung von von Bedingungen

Mehr

Java-Schulung Grundlagen

Java-Schulung Grundlagen Java-Schulung Grundlagen Java 2 Standard Edition JDK 5 / 6 31.05.2008 Marcel Wieczorek 1 Themenübersicht Basiswissen Objektorientierung Datentypen Fehlerbehandlung Sonstiges Einführung Klassen, Strings

Mehr

Ereignisbehandlung 21

Ereignisbehandlung 21 Ereignisbehandlung 21 3 Ereignisbehandlung Dieses Kapitel beschäftigt sich mit der Ereignisbehandlung, d.h. der Reaktion eines Programms auf Eingaben durch benutzende Personen. Nach einigen ersten Beispielen

Mehr

Java Real-Time Specification

Java Real-Time Specification Ausgewählte Kapitel eingebetteter Systeme Java Real-Time Specification Tobias Distler 05.07.2006 Java und Echtzeit? Problem Nichtdeterministisches Verhalten der Garbage Collection Weitere Nachteile Scheduling

Mehr

VIII: Vererbung. Unterklassen einer Klasse. Vererbung von Methoden und Instanzvariablen. Überschreiben von Methoden

VIII: Vererbung. Unterklassen einer Klasse. Vererbung von Methoden und Instanzvariablen. Überschreiben von Methoden VIII: Vererbung Unterklassen einer Klasse Vererbung von Methoden und Instanzvariablen Überschreiben von Methoden Vererbung als Realisierung einer is-a Beziehung. Informatik I VIII: Vererbung 259 Beispiel:

Mehr

Test zu Grundlagen der Programmierung Leitung: Michael Hahsler. 21. November 2003

Test zu Grundlagen der Programmierung Leitung: Michael Hahsler. 21. November 2003 Test zu Grundlagen der Programmierung Leitung: Michael Hahsler 1. November 00 Name Martrikelnummer Unterschrift Bitte kreuzen Sie das Studium an, für das Sie diese Prüfung ablegen: O Bakkalaureat Wirtschaftsinformatik

Mehr

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java: Technische Informatik für Ingenieure (TIfI) WS 2005/2006, Vorlesung 9 II. Grundlagen der Programmierung Ekkart Kindler Funktionen und Prozeduren Datenstrukturen 9. Datenstrukturen Daten zusammenfassen

Mehr

Prof. Dr. Uwe Schmidt. 21. August 2007. Aufgaben zur Klausur Objektorientierte Programmierung im SS 2007 (IA 252)

Prof. Dr. Uwe Schmidt. 21. August 2007. Aufgaben zur Klausur Objektorientierte Programmierung im SS 2007 (IA 252) Prof. Dr. Uwe Schmidt 21. August 2007 Aufgaben zur Klausur Objektorientierte Programmierung im SS 2007 (IA 252) Zeit: 75 Minuten erlaubte Hilfsmittel: keine Bitte tragen Sie Ihre Antworten und fertigen

Mehr

Tutorium Java Ein Überblick. Helge Janicke

Tutorium Java Ein Überblick. Helge Janicke Tutorium Java Ein Überblick Helge Janicke 26. Oktober 2000 1 VORRAUSSETZUNGEN ZUM PROGRAMMIEREN MIT JAVA. 1 1 Vorraussetzungen zum Programmieren mit Java. Was braucht man, wenn man mit Java programmieren

Mehr

Grundlagen der Informatik für Ingenieure I

Grundlagen der Informatik für Ingenieure I 3 Einführung in das objektorientierte Programmier-Paradigma 3 Einführung in das objektorientierte Programmier-Paradigma 3.1.1 Top-down structured design 3.1.2 Data-driven design 3.1.3 Object-oriented design

Mehr

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

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 Servlet Debugging Markus Völter, voelter@acm.org, www.voelter.de Bei der Arbeit mit Servlets kommt man recht schnell an den Punkt, an dem man Servlets vernünftig testen oder debuggen will. Mit Hilfe des

Mehr

Java Programmierung auf der Konsole / unter Eclipse

Java Programmierung auf der Konsole / unter Eclipse Fakultät Informatik, HFU Brückenkurs Programmieren 1 Java Programmierung auf der Konsole / unter Eclipse Allgemeine Begriffe Programmiersprache: künstliche Sprache zur Notation von Programmen Programm:

Mehr