Rainer Oechsle
Parallele und verteilte Anwendungen in Java
Vorwort zur 5. Auflage
6
Inhalt
10
1 Einleitung
16
1.1 Parallelität, Nebenläufigkeit und Verteilung
16
1.2 Programme, Prozesse und Threads
17
2 Grundlegende Synchronisationskonzepte in Java
21
2.1 Erzeugung und Start von Java-Threads
21
2.1.1 Ableiten der Klasse Thread
21
2.1.2 Implementieren der Schnittstelle Runnable
23
2.1.3 Einige Beispiele
26
2.2 Probleme beim Zugriff auf gemeinsam genutzte Objekte
32
2.2.1 Erster Lösungsversuch
36
2.2.2 Zweiter Lösungsversuch
37
2.3 Synchronized und volatile
39
2.3.1 Synchronized-Methoden
39
2.3.2 Synchronized-Blöcke
40
2.3.3 Wirkung von synchronized
42
2.3.4 Notwendigkeit von synchronized
43
2.3.5 Volatile
44
2.3.6 Regel für die Nutzung von synchronized
45
2.4 Ende von Java-Threads
46
2.4.1 Asynchrone Beauftragung mit Abfragen der Ergebnisse
47
2.4.2 Zwangsweises Beenden von Threads
53
2.4.3 Asynchrone Beauftragung mit befristetem Warten
58
2.4.4 Asynchrone Beauftragung mit Rückruf (Callback)
60
2.4.5 Asynchrone Beauftragung mit Rekursion
63
2.5 Wait und notify
66
2.5.1 Erster Lösungsversuch
67
2.5.2 Zweiter Lösungsversuch
68
2.5.3 Dritter Lösungsversuch
69
2.5.4 Korrekte und effiziente Lösung mit wait und notify
70
2.6 NotifyAll
78
2.6.1 Erzeuger-Verbraucher-Problem mit wait und notify
79
2.6.2 Erzeuger-Verbraucher-Problem mit wait und notifyAll
83
2.6.3 Faires Parkhaus mit wait und notifyAll
85
2.7 Prioritäten von Threads
87
2.8 Thread-Gruppen
94
2.9 Vordergrund- und Hintergrund-Threads
99
2.10 Weitere „gute“ und „schlechte“ Thread-Methoden
100
2.11 Thread-lokale Daten
102
2.12 Zusammenfassung
104
3 Fortgeschrittene Synchronisationskonzepte in Java
109
3.1 Semaphore
110
3.1.1 Einfache Semaphore
110
3.1.2 Einfache Semaphore für den gegenseitigen Ausschluss
111
3.1.3 Einfache Semaphore zur Herstellung vorgegebener Ausführungsreihenfolgen
113
3.1.4 Additive Semaphore
116
3.1.5 Semaphorgruppen
119
3.2 Message Queues
122
3.2.1 Verallgemeinerung des Erzeuger-Verbraucher-Problems
122
3.2.2 Übertragung des erweiterten Erzeuger-Verbraucher-Problems auf Message Queues
124
3.3 Pipes
127
3.4 Philosophen-Problem
130
3.4.1 Lösung mit synchronized – wait – notifyAll
131
3.4.2 Naive Lösung mit einfachen Semaphoren
133
3.4.3 Einschränkende Lösung mit gegenseitigem Ausschluss
135
3.4.4 Gute Lösung mit einfachen Semaphoren
136
3.4.5 Lösung mit Semaphorgruppen
139
3.5 Leser-Schreiber-Problem
141
3.5.1 Lösung mit synchronized – wait – notifyAll
142
3.5.2 Lösung mit additiven Semaphoren
146
3.6 Schablonen zur Nutzung der Synchronisationsprimitive und Konsistenzbetrachtungen
147
3.7 Concurrent-Klassenbibliothek aus Java 5
151
3.7.1 Executors
152
3.7.2 Locks und Conditions
158
3.7.3 Atomic-Klassen
166
3.7.4 Synchronisationsklassen
170
3.7.5 Queues
173
3.8 Das Fork-Join-Framework von Java 7
174
3.8.1 Grenzen von ThreadPoolExecutor
174
3.8.2 ForkJoinPool und RecursiveTask
176
3.8.3 Beispiel zur Nutzung des Fork-Join-Frameworks
178
3.9 Das Data-Streaming-Framework von Java 8
181
3.9.1 Einleitendes Beispiel
181
3.9.2 Sequenzielles Data-Streaming
183
3.9.3 Paralleles Data-Streaming
187
3.10 Die Completable Futures von Java 8
188
3.11 Ursachen für Verklemmungen
195
3.11.1 Beispiele für Verklemmungen mit synchronized
196
3.11.2 Beispiele für Verklemmungen mit Semaphoren
199
3.11.3 Bedingungen für das Eintreten von Verklemmungen
200
3.12 Vermeidung von Verklemmungen
201
3.12.1 Anforderung von Betriebsmitteln „auf einen Schlag“
204
3.12.2 Anforderung von Betriebsmitteln gemäß einer vorgegebenen Ordnung
205
3.12.3 Weitere Verfahren
206
3.13 Zusammenfassung
208
4 Parallelität und grafische Benutzeroberflächen
210
4.1 Einführung in die Programmierung grafischer Benutzeroberflächen mit JavaFX
211
4.1.1 Allgemeines zu grafischen Benutzeroberflächen
211
4.1.2 Erstes JavaFX-Beispiel
212
4.1.3 Ereignisbehandlung
213
4.2 Properties, Bindings und JavaFX-Collections
217
4.2.1 Properties
217
4.2.2 Bindings
220
4.2.3 JavaFX-Collections
222
4.3 Elemente von JavaFX
222
4.3.1 Container
222
4.3.2 Interaktionselemente
225
4.3.3 Grafikprogrammierung
227
4.3.4 Weitere Funktionen von JavaFX
233
4.4 MVP
234
4.4.1 Prinzip von MVP
235
4.4.2 Beispiel zu MVP
236
4.5 Threads und JavaFX
243
4.5.1 Threads für JavaFX
243
4.5.2 Länger dauernde Ereignisbehandlungen
244
4.5.3 Beispiel Stoppuhr
249
4.5.4 Tasks und Services in JavaFX
255
4.6 Zusammenfassung
264
5 Verteilte Anwendungen mit Sockets
265
5.1 Einführung in das Themengebiet der Rechnernetze
266
5.1.1 Schichtenmodell
266
5.1.2 IP-Adressen und DNS-Namen
270
5.1.3 Das Transportprotokoll UDP
271
5.1.4 Das Transportprotokoll TCP
272
5.2 Socket-Schnittstelle
273
5.2.1 Socket-Schnittstelle zu UDP
273
5.2.2 Socket-Schnittstelle zu TCP
275
5.2.3 Socket-Schnittstelle für Java
277
5.3 Kommunikation über UDP mit Java-Sockets
278
5.4 Multicast-Kommunikation mit Java-Sockets
287
5.5 Kommunikation über TCP mit Java-Sockets
291
5.6 Sequenzielle und parallele Server
301
5.6.1 TCP-Server mit dynamischer Parallelität
302
5.6.2 TCP-Server mit statischer Parallelität
306
5.6.3 Sequenzieller, „verzahnt“ arbeitender TCP-Server
311
5.7 Zusammenfassung
315
6 Verteilte Anwendungen mit RMI
316
6.1 Prinzip von RMI
316
6.2 Einführendes RMI-Beispiel
319
6.2.1 Basisprogramm
319
6.2.2 RMI-Client mit grafischer Benutzeroberfläche
323
6.2.3 RMI-Registry
328
6.3 Parallelität bei RMI-Methodenaufrufen
332
6.4 Wertübergabe für Parameter und Rückgabewerte
336
6.4.1 Serialisierung und Deserialisierung von Objekten
337
6.4.2 Serialisierung und Deserialisierung bei RMI
342
6.5 Referenzübergabe für Parameter und Rückgabewerte
346
6.6 Transformation lokaler in verteilte Anwendungen
361
6.6.1 Rechnergrenzen überschreitende Synchronisation mit RMI
361
6.6.2 Asynchrone Kommunikation mit RMI
364
6.6.3 Verteilte MVP-Anwendungen mit RMI
365
6.7 Dynamisches Umschalten zwischen Wert- und Referenzübergabe – Migration von Objekten
366
6.7.1 Das Exportieren und „Unexportieren“ von Objekten
366
6.7.2 Migration von Objekten
369
6.7.3 Eintrag eines Nicht-Stub-Objekts in die RMI-Registry
376
6.8 Laden von Klassen über das Netz
377
6.9 Realisierung von Stubs und Skeletons
378
6.9.1 Realisierung von Skeletons
379
6.9.2 Realisierung von Stubs
379
6.10 Verschiedenes
382
6.11 Zusammenfassung
383
7 Webbasierte Anwendungen mit Servlets und JSF
384
7.1 HTTP und HTML
385
7.1.1 GET
385
7.1.2 Formulare in HTML
388
7.1.3 POST
390
7.1.4 Format von HTTP-Anfragen und -Antworten
391
7.2 Einführende Servlet-Beispiele
392
7.2.1 Allgemeine Vorgehensweise
392
7.2.2 Erstes Servlet-Beispiel
393
7.2.3 Zugriff auf Formulardaten
395
7.2.4 Zugriff auf die Daten der HTTP-Anfrage und -Antwort
397
7.3 Parallelität bei Servlets
398
7.3.1 Demonstration der Parallelität von Servlets
398
7.3.2 Paralleler Zugriff auf Daten
400
7.3.3 Anwendungsglobale Daten
404
7.4 Sessions und Cookies
407
7.4.1 Sessions
408
7.4.2 Realisierung von Sessions mit Cookies
412
7.4.3 Direkter Zugriff auf Cookies
414
7.4.4 Servlets mit länger dauernden Aufträgen
415
7.5 Asynchrone Servlets
421
7.6 Filter
425
7.7 Übertragung von Dateien mit Servlets
426
7.7.1 Herunterladen von Dateien
426
7.7.2 Hochladen von Dateien
429
7.8 JSF (Java Server Faces)
432
7.8.1 Einführendes Beispiel
432
7.8.2 Managed Beans und deren Scopes
439
7.8.3 MVP-Prinzip mit JSF
443
7.8.4 AJAX mit JSF
444
7.9 RESTful WebServices
448
7.9.1 Definition von RESTful WebServices
449
7.9.2 JSON
450
7.9.3 Beispiel
452
7.10 WebSockets
457
7.11 Zusammenfassung
461
Literatur
464
Index
466
© 2009-2024 ciando GmbH