|
Vorwort zur 3. Auflage |
6 |
|
|
Inhalt |
10 |
|
|
1 Einleitung |
14 |
|
|
1.1 Parallelität, Nebenläufigkeit und Verteilung |
14 |
|
|
1.2 Programme, Prozesse und Threads |
15 |
|
|
2 Grundlegende Synchronisationskonzepte in Java |
20 |
|
|
2.1 Erzeugung und Start von Java-Threads |
20 |
|
|
2.1.1 Ableiten der Klasse Thread |
20 |
|
|
2.1.2 Implementieren der Schnittstelle Runnable |
22 |
|
|
2.1.3 Einige Beispiele |
23 |
|
|
2.2 Probleme beim Zugriff auf gemeinsam genutzte Objekte |
29 |
|
|
2.2.1 Erster Lösungsversuch |
32 |
|
|
2.2.2 Zweiter Lösungsversuch |
34 |
|
|
2.3 Synchronized und volatile |
36 |
|
|
2.3.1 Synchronized-Methoden |
36 |
|
|
2.3.2 Synchronized-Blöcke |
37 |
|
|
2.3.3 Wirkung von synchronized |
38 |
|
|
2.3.4 Notwendigkeit von synchronized |
40 |
|
|
2.3.5 Volatile |
41 |
|
|
2.3.6 Regel für die Nutzung von synchronized |
41 |
|
|
2.4 Ende von Java-Threads |
43 |
|
|
2.4.1 Asynchrone Beauftragung mit Abfragen der Ergebnisse |
44 |
|
|
2.4.2 Zwangsweises Beenden von Threads |
49 |
|
|
2.4.3 Asynchrone Beauftragung mit befristetem Warten |
54 |
|
|
2.4.4 Asynchrone Beauftragung mit Rückruf (Callback) |
55 |
|
|
2.5 Wait und notify |
58 |
|
|
2.5.1 Erster Lösungsversuch |
58 |
|
|
2.5.2 Zweiter Lösungsversuch |
59 |
|
|
2.5.3 Korrekte Lösung mit wait und notify |
60 |
|
|
2.6 NotifyAll |
68 |
|
|
2.6.1 Erzeuger-Verbraucher-Problem mit wait und notify |
69 |
|
|
2.6.2 Erzeuger-Verbraucher-Problem mit wait und notifyAll |
72 |
|
|
2.6.3 Faires Parkhaus mit wait und notifyAll |
75 |
|
|
2.7 Prioritäten von Threads |
76 |
|
|
2.8 Thread-Gruppen |
83 |
|
|
2.9 Vordergrund- und Hintergrund-Threads |
87 |
|
|
2.10 Weitere „gute“ und „schlechte“ Thread-Methoden |
89 |
|
|
2.11 Thread-lokale Daten |
90 |
|
|
2.12 Zusammenfassung |
93 |
|
|
3 Fortgeschrittene Synchronisationskonzepte in Java |
98 |
|
|
3.1 Semaphore |
99 |
|
|
3.1.1 Einfache Semaphore |
99 |
|
|
3.1.2 Einfache Semaphore für den gegenseitigen Ausschluss |
100 |
|
|
3.1.3 Einfache Semaphore zur Herstellung vorgegebener Ausführungsreihenfolgen |
102 |
|
|
3.1.4 Additive Semaphore |
105 |
|
|
3.1.5 Semaphorgruppen |
107 |
|
|
3.2 Message Queues |
109 |
|
|
3.2.1 Verallgemeinerung des Erzeuger-Verbraucher-Problems |
109 |
|
|
3.2.2 Übertragung des erweiterten Erzeuger-Verbraucher-Problems auf Message Queues |
112 |
|
|
3.3 Pipes |
114 |
|
|
3.4 Philosophen-Problem |
117 |
|
|
3.4.1 Lösung mit synchronized – wait – notifyAll |
118 |
|
|
3.4.2 Naive Lösung mit einfachen Semaphoren |
120 |
|
|
3.4.3 Einschränkende Lösung mit gegenseitigem Ausschluss |
121 |
|
|
3.4.4 Gute Lösung mit einfachen Semaphoren |
122 |
|
|
3.4.5 Lösung mit Semaphorgruppen |
125 |
|
|
3.5 Leser-Schreiber-Problem |
127 |
|
|
3.5.1 Lösung mit synchronized – wait – notifyAll |
128 |
|
|
3.5.2 Lösung mit additiven Semaphoren |
131 |
|
|
3.6 Schablonen zur Nutzung der Synchronisationsprimitive und Konsistenzbetrachtungen |
132 |
|
|
3.7 Concurrent-Klassenbibliothek aus Java 5 |
136 |
|
|
3.7.1 Executors |
136 |
|
|
3.7.2 Locks und Conditions |
142 |
|
|
3.7.3 Atomic-Klassen |
149 |
|
|
3.7.4 Synchronisationsklassen |
150 |
|
|
3.7.5 Queues |
152 |
|
|
3.8 Ursachen für Verklemmungen |
154 |
|
|
3.8.1 Beispiele für Verklemmungen mit synchronized |
155 |
|
|
3.8.2 Beispiele für Verklemmungen mit Semaphoren |
158 |
|
|
3.8.3 Bedingungen für das Eintreten von Verklemmungen |
159 |
|
|
3.9 Vermeidung von Verklemmungen |
160 |
|
|
3.9.1 Anforderung von Betriebsmitteln „auf einen Schlag“ |
163 |
|
|
3.9.2 Anforderung von Betriebsmitteln gemäß einer vorgegebenen Ordnung |
164 |
|
|
3.9.3 Anforderung von Betriebsmitteln mit Bedarfsanalyse |
165 |
|
|
3.10 Modellierung mit Petri-Netzen |
172 |
|
|
3.10.1 Petri-Netze |
172 |
|
|
3.10.2 Modellierung der Nutzung von Synchronized-Methoden |
174 |
|
|
3.10.3 Modellierung von wait, notify und notifyAll |
177 |
|
|
3.11 Zusammenfassung |
180 |
|
|
4 Parallelität und grafische Benutzeroberflächen |
182 |
|
|
4.1 Einführung in die Programmierung grafischer Benutzeroberflächen mit Swing |
183 |
|
|
4.1.1 Einige erste Beispiele |
183 |
|
|
4.1.2 Ereignisbehandlung |
187 |
|
|
4.1.3 Container |
191 |
|
|
4.1.4 Primitive Interaktionselemente |
194 |
|
|
4.1.5 Grafikprogrammierung |
195 |
|
|
4.1.6 Applets |
200 |
|
|
4.2 MVC |
202 |
|
|
4.2.1 Prinzip von MVC |
203 |
|
|
4.2.2 MVC für die Entwicklung eigener Programme |
206 |
|
|
4.2.3 MVC in Swing |
211 |
|
|
4.3 Threads und Swing |
213 |
|
|
4.4 Zusammenfassung |
224 |
|
|
5 Verteilte Anwendungen mit Sockets |
226 |
|
|
5.1 Einführung in das Themengebiet der Rechnernetze |
227 |
|
|
5.1.1 Schichtenmodell |
227 |
|
|
5.1.2 IP-Adressen und DNS-Namen |
231 |
|
|
5.1.3 Das Transportprotokoll UDP |
232 |
|
|
5.1.4 Das Transportprotokoll TCP |
234 |
|
|
5.2 Socket-Schnittstelle |
235 |
|
|
5.2.1 Socket-Schnittstelle zu UDP |
235 |
|
|
5.2.2 Socket-Schnittstelle zu TCP |
236 |
|
|
5.2.3 Socket-Schnittstelle für Java |
239 |
|
|
5.3 Kommunikation über UDP mit Java-Sockets |
240 |
|
|
5.4 Multicast-Kommunikation mit Java-Sockets |
247 |
|
|
5.5 Kommunikation über TCP mit Java-Sockets |
251 |
|
|
5.6 Sequenzielle und parallele Server |
261 |
|
|
5.6.1 Server mit dynamischer Parallelität |
263 |
|
|
5.6.2 Server mit statischer Parallelität |
267 |
|
|
5.7 Zusammenfassung |
272 |
|
|
6 Verteilte Anwendungen mit RMI |
274 |
|
|
6.1 Prinzip von RMI |
274 |
|
|
6.2 Einführendes RMI-Beispiel |
277 |
|
|
6.2.1 Basisprogramm |
277 |
|
|
6.2.2 RMI-Client mit grafischer Benutzeroberfläche |
281 |
|
|
6.2.3 RMI-Registry |
284 |
|
|
6.3 Parallelität bei RMI-Methodenaufrufen |
288 |
|
|
6.4 Wertübergabe für Parameter und Rückgabewerte |
292 |
|
|
6.4.1 Serialisierung und Deserialisierung von Objekten |
293 |
|
|
6.4.2 Serialisierung und Deserialisierung bei RMI |
297 |
|
|
6.5 Referenzübergabe für Parameter und Rückgabewerte |
301 |
|
|
6.6 Transformation lokaler in verteilte Anwendungen |
317 |
|
|
6.6.1 Rechnergrenzen überschreitende Synchronisation mit RMI |
318 |
|
|
6.6.2 Asynchrone Kommunikation mit RMI |
320 |
|
|
6.6.3 Verteilte MVC-Anwendungen mit RMI |
320 |
|
|
6.7 Dynamisches Umschalten zwischen Wert- und Referenzübergabe – Migration von Objekten |
322 |
|
|
6.7.1 Das Exportieren und „Unexportieren“ von Objekten |
322 |
|
|
6.7.2 Migration von Objekten |
325 |
|
|
6.7.3 Eintrag eines Nicht-Stub-Objekts in die RMI-Registry |
332 |
|
|
6.8 Laden von Klassen über das Netz |
333 |
|
|
6.9 Realisierung von Stubs und Skeletons |
334 |
|
|
6.9.1 Realisierung von Skeletons |
334 |
|
|
6.9.2 Realisierung von Stubs |
335 |
|
|
6.10 Verschiedenes |
337 |
|
|
6.11 Zusammenfassung |
338 |
|
|
7 Webbasierte Anwendungen mit Servlets und JSP |
340 |
|
|
7.1 HTTP |
341 |
|
|
7.1.1 GET |
341 |
|
|
7.1.2 Formulare |
344 |
|
|
7.1.3 POST |
346 |
|
|
7.1.4 Format von HTTP-Anfragen und -Antworten |
347 |
|
|
7.2 Einführende Servlet-Beispiele |
348 |
|
|
7.2.1 Allgemeine Vorgehensweise |
348 |
|
|
7.2.2 Erstes Servlet-Beispiel |
349 |
|
|
7.2.3 Zugriff auf Formulardaten |
356 |
|
|
7.2.4 Zugriff auf die Daten der HTTP-Anfrage und -Antwort |
357 |
|
|
7.3 Parallelität bei Servlets |
358 |
|
|
7.3.1 Demonstration der Parallelität von Servlets |
358 |
|
|
7.3.2 Paralleler Zugriff auf Daten |
360 |
|
|
7.3.3 Anwendungsglobale Daten |
363 |
|
|
7.4 Sessions und Cookies |
366 |
|
|
7.4.1 Sessions |
367 |
|
|
7.4.2 Realisierung von Sessions mit Cookies |
372 |
|
|
7.4.3 Direkter Zugriff auf Cookies |
373 |
|
|
7.4.4 Servlets mit länger dauernden Aufträgen |
375 |
|
|
7.5 Übertragung von Dateien mit Servlets |
379 |
|
|
7.5.1 Herunterladen von Dateien |
379 |
|
|
7.5.2 Hochladen von Dateien |
382 |
|
|
7.6 JSP (Java Server Pages) |
385 |
|
|
7.6.1 Scripting-Elemente |
385 |
|
|
7.6.2 Direktiven |
387 |
|
|
7.6.3 Aktionen |
388 |
|
|
7.7 MVC-Prinzip mit Servlets und JSPs |
391 |
|
|
7.8 MVC-Prinzip mit AJAX und GWT |
398 |
|
|
7.9 Zusammenfassung |
406 |
|
|
Literatur |
408 |
|
|
Register |
410 |
|