Ausgewählte Implementierungsprobleme - TZI

Werbung
Einführung
Multithreading
Serialisierung
Literatur
Ausgewählte Implementierungsprobleme
Rebecca Tiarks
18. Dezember 2008
1 / 30
Einführung
Multithreading
Serialisierung
Literatur
Inhaltsverzeichnis
1
Einführung
2
Multithreading
Synchronisation
3
Serialisierung
Persistenzproblem & CSV
Binärformat
Serialisierung
2 / 30
Einführung
Multithreading
Serialisierung
Literatur
Themenübersicht
1
18. Dez: Multithreading + Serialisierung
2
8. Jan. Swing
3
15. Jan TCP, Sockets
4
22. Jan SSL, RMI
5
29. JDBC, OR-Mapper (Hibernate, JPox, Java Persistence
API, Castor, ...)
3 / 30
Einführung
Multithreading
Serialisierung
Literatur
Ablauf
http://www.informatik.unibremen.de/st/Lehre/swp0809/Implementierungsprobleme/index.html
1
Beispielcode zum Ausprobieren auf der Webseite
2
Übungsblatt zu den Themen
3
Musterlösung wird online gestellt
4 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Threads und Nebenläufigkeit
Nebenläufigkeit - mehrere Programme gleichzeitig
Umschaltung übernimmt Scheduler des Betriebssystems
aktive Programme bestehen aus Prozessen
pro Prozess mind. ein Thread der Code ausführt
5 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Threads in Java
wenn BS Threads unterstützt - direkte Abbildung
ansonsten Abbildung durch VM
Threads sind Objekte
in Java verschiedene Klassen, Schnittstellen für Multithreading
Thread, Runnable, Lock, Condition, ThreadGroup
Erzeugung von Threads auf zwei Arten
Implementierung des Interfaces java.lang.Runnable
Ableiten von der Klasse Thread (die das Interface Runnable
implementiert)
6 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Die Schnittstelle Runnable
Was Thread tun soll wird in Runnable verpackt und Thread
übergeben
nur die Methode run() ist vorgeschrieben
enthält Anweisungen die Parallel ausgeführt werden sollen und
ist Startpunkt eines Threads
zum Starten muss ein Thread-Objekt mit der Referenz auf
das Runnable erzeugt werden und gestartet werden
start()
7 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Beispiel
class Test implements Runnable
{
public void run ()
{
for ( int i = 0; i < 20; i ++ )
System . out . println ( i );
}
}
Erzeugen und Starten eines Thread-Objekts
Thread test = new Thread ( new Test () );
test . start ();
8 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Beispiel
Verbesserung: Runnable verwaltet Thread selber
automatisches Starten im Konstruktor mit this-Referenz
class Test implements Runnable
{
Test ()
{
new Thread ( this ). start ();
}
public void run ()
{
for ( int i = 0; i < 20; i ++ )
System . out . println ( i );
}
}
9 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Erweitern der Klasse Thread
implementiert Runnable
stellt run() Methode zur Verfügung
es muss kein Runnable-Exemplar mehr im Konstruktur
eingefügt werden
Starten durch den Aufruf von start()
dadurch wird neuer Thread erzeugt und run() aufgerufen
10 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Beispiel
public class Test extends Thread
{
public void run ()
{
for ( int i = 0; i < 20; i ++ )
System . out . println ( i );
}
}
Erzeugen und Starten:
Thread test = new Test ( );
test . start ();
11 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Erweitern der Klasse Thread
durch Erweitern können Methoden direkt genutzt werden
getName() currentThread()
nur einmaliges Ableiten möglich
12 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Zustände eines Threads
Neu: wurde erzeugt, aber noch nicht gestartet
Lauffähig: laufend oder ausführbar
Blockiert: wartend, I/O-blockiert, gesperrt, suspendiert
Tot: ausführung beendet
13 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Threads schlafen legen
Threads können angehalten werden
Klassenfunktion Thread.sleep() (statische Funktion, keine
Objektmethode )
static void sleep( long millis ) throws
InterruptedException
muss in einem try-catch-Block stehen da Exception
ausgelöst wird.
try {
Thread . sleep ( 2000 );
} catch ( I nterruptedException e ) { }
14 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Prioritäten
Zahl zwischen 1 und 10
Thread.MIN PRIORITY Thread.MAX PRIORITY
final int getPriority()
setPriority( int newPriority )
mit yield() kann ein Thread eine Runde aussetzen
reiht sich in die Threadwarteschlange ein
15 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Unterbrechung
Unterbrechung z.B. bei Endlosschleife
interrupted(), isInterrupted(), interrupt()
interrupt() setzt Flag das mit isInterrupted() abgefragt
werden kann
interrupted() fragt Status ab und löscht diesen
sleep(), wait(), join() lösen InterruptException aus
nach Unterbrechung
16 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Warten auf einen Thread
Warten auf das Ende einer Aktivität (z.B. bei mehreren
Threads)
final void join() throws InterruptedException
oder mit Zeitangabe
final void join( long millis ) throws
InterruptedException (wartet höchstens so lange wie
angegeben)
void wait () throws Exception
{
Thread test = new Test ();
test . start ();
test . join ();
// warte bis Thread test terminiert
}
17 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Daemon-Threads
Applikation ist beendet wenn alle Threads terminiert sind
Ausnahme: Daemon-Threads
werden beendet wenn der letzte nicht Daemon-Thread einer
Anwendung terminiert hat.
final void setDaemon( boolean on ) nur vor dem Start
final boolean isDaemon()
18 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Gemeinsamer Zugriff
Zugriff von mehreren Threads auf gemeinsame Daten
Thread kann während der Arbeit unterbrochen werden
atomare Operation: arbeit während der keine Unterbrechung
stattfinden kann
selbst einfache Anweisungen wie i++ sind nicht atomar
19 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Gemeinsamer Zugriff
in Java Monitore
Baisklasse Object bietet Locks
jedes Objekt hat einen Schlüssel, Thread kann Schlüssel
anfordern
zwei Möglichkeiten:
synchronized
oder mit Klassen aus java.util.concurrent.lock (seit
Java 5.0)
20 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
ReentrantLock
Schnittstelle Lock
kritischer Abschnitt beginnt mit lock und endet mit
unlock()
final Lock lock = new ReentrantLock ();
Runnable r = new Runnable ()
{
public void run ()
{ ...
// tue etwas
lock . lock ();
// kritischer Abschnitt
...
lock . unlock ();
}
};
21 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
ReentrantLock
ReentrantLock() erzeugt Lock-Objekt
lock() und unlock()
tryLock() wartet nicht sondern kehrt mit false zurück
lockInterruptibly() wartet und kann unterbrochen werden
zusätzlich gibt es noch die Schnittstelle
ReentrantReadWriteLock
22 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
synchronized
schützen von kritischen Abschnitten durch synchronized
bei statischen Methoden vom Class-Objekt
Thread setzt bei Objektfunktionen Monitor this-Objekts
bei Blöcken keine this-Referenz deshalb Objekt anlegen
class Test
{
private static final Object o = new Object ();
static void doTest ()
{
synchronized ( o )
{
// ...
}
}
}
23 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Benachrichtigungen
Beispiel: Produzent (Clientverbindung auf dem Server) und
Konsument (Verarbeiter) haben eine Liste von noch offenen
Aufgaben als gemeinsame Daten.
Problem: wie kann der Produzent den Konsumenten
benachrichtigen, dass es neue Aufgaben gibt? Bzw. wie kann
der Konsument auf neue Aufgaben warten?
Thread möchte Ankommen von Informationen signalisieren
andere Threads wollen Benachrichtigt werden wenn Infos da
sind
Idee: Abfragen in Schleife ob es neue Infos gibt
24 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
Benachrichtigungen
jedes Objekt besitzt die Methoden wait() und notify()
wait() gibt Lock vorübergehend frei und reiht Thread als
wartend auf das Objekt ein
notify(), notifyAll() wecken Threads wieder auf
synchronized ( o ) {
o . wait ( ) ;
}
synchronized ( o ) {
o . notify ();
// oder
o . notifyAll ();
}
25 / 30
Einführung
Multithreading
Serialisierung
Literatur
Synchronisation
ReentrantLock
ReentrantLock() repräsentiert Monitor
es wird über ein gemeinsames Condition-Objekt
kommuniziert
newCondition() liefert Condition-Objekt
kann mit await() und signal(), signalAll()
kommunizieren
vor dem Aufruf muss ein Bereich immer geschützt sein durch
ein lock()
26 / 30
Einführung
Multithreading
Serialisierung
Literatur
Persistenzproblem & CSV
Binärformat
Serialisierung
Persistenzproblem
Anforderungen: Zeiterfassung im offline-Modus, keine
Datenbank auf dem Klienten
Eingaben müssen bis zur nächsten Serververbindung
gespeichert werden
Gewünscht ist Mechanismus der Objektstruktur und
Variablenbelegung zu einer bestimmten Zeit sicher
(persistent) macht und an anderer Stelle wieder hervorholt.
alle Infos wie Objekttyp, Variablentyp, Unterobjekte müssen
enthalten sein.
Idee:
eine CSV-Datei (comma seperated values)
zum Schreiben java.io.PrintWriter
zum Lesen java.io.BufferedReader
< firstname >; < lastname >; < login >; < matrikulationNumber >; < mark >
27 / 30
Einführung
Multithreading
Serialisierung
Literatur
Persistenzproblem & CSV
Binärformat
Serialisierung
Binärformat
Probleme: bei CSV müssen die speziellen Zeichen Semikolon
und Newline verhindert werden
eine mögliche Lösung: URL-Format, z.B. %3B statt ;
eine andere: Länge voranstellen: 6:Thomas
Idee: Binärformat
schreiben mit java.io.DataOutputStream, lesen mit
java.io.DataInputStream
für jeden Primitivtype eine readXXX() und writeXXX()
Methode
readUTF() und writeUTF() für Strings
28 / 30
Einführung
Multithreading
Serialisierung
Literatur
Persistenzproblem & CSV
Binärformat
Serialisierung
Objekte
Geht es einfacher? Ja!
Java kennt die einzelnen Felder der Klassen auch selber
Serialisierung
schreiben mit
java.io.ObjectOutputStream.writeObject(), lesen mit
java.io.ObjectInputStream.readObject()
Klassen müssen das Markierungsinterface
java.io.Serializable implementieren, um zu zeigen, dass
sie mit der Serialisierung einverstanden sind
writeObject() bildet einen Objektgraphen auf einen
Bytestrom ab
alle durch das Startobjekt erreichbaren Objekte werden
serialisiert → manchmal wird mehr serialisiert, als man
wünscht
Container wie ArrayList implementieren auch Serializable
→ man kann gleich den ganzen Container serialisieren
29 / 30
Einführung
Multithreading
Serialisierung
Literatur
Christian Ullenboom. Java ist auch eine Insel. Galileo Computing,
7 edition, 2008. ISBN 978-3-8362-1146-8.
30 / 30
Herunterladen