1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
|
<html>
<head>
<title>
Handbuch der Java-Programmierung, 5. Auflage
</title>
</head>
<body>
<a name="startofbody"></a>
<script language="JavaScript" src="hjp4lib.js">
</script>
<script language="JavaScript">
installKbdHandler("97,#startofbody;101,#endofbody;116,cover.html;122,k100003.html;115,search.html;105,index.html;100,JDKDOCS;112,APIDOCS;104,k100143.html;106,k100144.html;107,k100146.html;108,k100150.html");
</script>
<table border=0 cellpadding=0 cellspacing=1 width="100%">
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html"> Titel </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html"> Inhalt </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html"> Suchen </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html"> Index </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()"> DOC </a>
<td align="right">Handbuch der Java-Programmierung, 5. Auflage
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100143.html"> << </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100144.html"> < </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100146.html"> > </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100150.html"> >> </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()"> API </a>
<td align="right">Kapitel 22 - Multithreading
</table>
<hr>
<!-- Section -->
<a name="sectlevel2id022002"></a>
<h2>22.2 Die Klasse Thread </h2>
<hr>
<ul>
<li><a href="k100145.html#sectlevel2id022002">22.2 Die Klasse Thread</a>
<ul>
<li><a href="k100145.html#neuerthread">22.2.1 Erzeugen eines neuen Threads</a>
<li><a href="k100145.html#threadabbrechen">22.2.2 Abbrechen eines Threads</a>
<li><a href="k100145.html#sectlevel3id022002003">22.2.3 Anhalten eines Threads</a>
<li><a href="k100145.html#weiterethreadmethoden">22.2.4 Weitere Methoden</a>
<ul>
<li><a href="k100145.html#sectlevel4id022002004001">sleep</a>
<li><a href="k100145.html#sectlevel4id022002004002">isAlive</a>
<li><a href="k100145.html#sectlevel4id022002004003">join</a>
</ul>
</ul>
</ul>
<hr>
<!-- Section -->
<a name="neuerthread"></a>
<h3>22.2.1 Erzeugen eines neuen Threads </h3>
<p>
Die Klasse <a href="index_t.html#ixb100591"><font color=#000080><tt>Thread</tt></font></a>
ist Bestandteil des Pakets <a href="index_j.html#ixb100188"><font color=#000080><tt>java.lang</tt></font></a>
und steht damit allen Anwendungen standardmäßig zur Verfügung.
<a href="index_t.html#ixb100591"><font color=#000080><tt>Thread</tt></font></a>
stellt die Basismethoden zur Erzeugung, Kontrolle und zum Beenden
von Threads zur Verfügung. Um einen konkreten Thread zu erzeugen,
muss eine eigene Klasse aus <a href="index_t.html#ixb100591"><font color=#000080><tt>Thread</tt></font></a>
abgeleitet und die Methode <a href="index_r.html#ixb101108"><font color=#000080><tt>run</tt></font></a>
überlagert werden.
<p>
Mit Hilfe eines Aufrufs der Methode <a name="ixa101467"><a href="index_s.html#ixb101110"><font color=#000080><tt>start</tt></font></a></a>
wird der Thread gestartet und die weitere Ausführung an die Methode
<a href="index_r.html#ixb101108"><font color=#000080><tt>run</tt></font></a>
übertragen. <a href="index_s.html#ixb101110"><font color=#000080><tt>start</tt></font></a>
wird nach dem Starten des Threads beendet, und der Aufrufer kann parallel
zum neu erzeugten Thread fortfahren.
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100%>
<tr>
<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=1></td>
<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top width=1000>
<p>
Die Methode <a href="index_r.html#ixb101108"><font color=#000080><tt>run</tt></font></a>
sollte vom Programm niemals direkt aufgerufen werden. Um einen Thread
zu starten, ist immer <a href="index_s.html#ixb101110"><font color=#000080><tt>start</tt></font></a>
aufzurufen. Dadurch wird der neue Thread erzeugt und initialisiert
und ruft schließlich selbst <a href="index_r.html#ixb101108"><font color=#000080><tt>run</tt></font></a>
auf, um den Anwendungscode auszuführen. Ein direkter Aufruf von
<a href="index_r.html#ixb101108"><font color=#000080><tt>run</tt></font></a>
würde dagegen keinen neuen Thread erzeugen, sondern wäre
ein normaler Methodenaufruf wie jeder andere und würde direkt
aus dem bereits laufenden Thread des Aufrufers erfolgen.</td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top>
<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#CC0000">
<tr>
<td><font color="#FFFFFF"> Warnung </font></td>
</tr>
</table>
</td>
<td width=1 align=left valign=top bgcolor="#CC0000"><img src="trp1_1.gif"></td>
</tr>
</table>
<p>
Das folgende Beispiel zeigt einen einfachen Thread, der in einer Endlosschleife
einen Zahlenwert hochzählt:
<a name="einfacherzaehlthread"></a>
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
<tr>
<td valign=top>
<font color="#000055">
<pre>
<font color="#555555">001 </font><font color="#00AA00">/* Listing2201.java */</font>
<font color="#555555">002 </font>
<font color="#555555">003 </font><font color="#0000AA">class</font> MyThread2201
<font color="#555555">004 </font><font color="#0000AA">extends</font> Thread
<font color="#555555">005 </font>{
<font color="#555555">006 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> run()
<font color="#555555">007 </font> {
<font color="#555555">008 </font> <font color="#006699">int</font> i = 0;
<font color="#555555">009 </font> <font color="#0000AA">while</font> (<font color="#006699">true</font>) {
<font color="#555555">010 </font> System.out.println(i++);
<font color="#555555">011 </font> }
<font color="#555555">012 </font> }
<font color="#555555">013 </font>}
<font color="#555555">014 </font>
<font color="#555555">015 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Listing2201
<font color="#555555">016 </font>{
<font color="#555555">017 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
<font color="#555555">018 </font> {
<font color="#555555">019 </font> MyThread2201 t = <font color="#0000AA">new</font> MyThread2201();
<font color="#555555">020 </font> t.start();
<font color="#555555">021 </font> }
<font color="#555555">022 </font>}</pre>
</font>
</td>
<td valign=top align=right>
<a href="../examples/Listing2201.java"><font color="#000055" size=-1>Listing2201.java</font></a></td>
</tr>
</table>
<i>
Listing 22.1: Ein einfacher Thread mit einem Zähler</i></p>
<p>
Zunächst wird hier ein neues Objekt vom Typ <font color="#000077"><tt>MyThread2201</tt></font>
instanziert. Die Ausführung eines Threads ist damit vorbereitet,
aber noch nicht tatsächlich erfolgt. Erst durch den Aufruf von
<a href="index_s.html#ixb101110"><font color=#000080><tt>start</tt></font></a>
wird ein neuer Thread erzeugt und durch einen impliziten Aufruf von
<a href="index_r.html#ixb101108"><font color=#000080><tt>run</tt></font></a>
der Thread-Body gestartet. Da das Programm in einer Endlosschleife
läuft, läßt es sich nur gewaltsam abbrechen (beispielsweise
durch Drücken von <font color="#007700"><tt>[STRG]</tt></font>+<font color="#007700"><tt>[C]</tt></font>).
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100%>
<tr>
<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top width=1000>
<p>
Im Gegensatz zu unseren bisherigen Beispielen wird dieses Programm
nicht automatisch nach <a href="index_m.html#ixb100150"><font color=#000080><tt>main</tt></font></a>
beendet. <a name="ixa101468"></a><a name="ixa101469"></a> Eine Java-Applikation
wird nämlich immer nach Ende des letzten Threads beendet, der
kein <a name="ixa101470"><i>Hintergrund-Thread</i></a> (<a name="ixa101471"><i>Dämon</i></a>)
ist. Da ein einfaches Programm nur einen einzigen Vordergrund-Thread
besitzt (nämlich den, in dem <a href="index_m.html#ixb100150"><font color=#000080><tt>main</tt></font></a>
läuft), wird es demnach beendet, wenn <a href="index_m.html#ixb100150"><font color=#000080><tt>main</tt></font></a>
beendet wird. Das Beispielprogramm erzeugt dagegen einen zusätzlichen
Vordergrund-Thread und kann damit vom Interpreter erst dann beendet
werden, wenn auch dieser Thread beendet wurde. Durch Aufruf von <a href="index_e.html#ixb100651"><font color=#000080><tt>exit</tt></font></a>
lassen sich auch Programme mit laufenden Vordergrund-Threads abbrechen.</td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top>
<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
<tr>
<td><font color="#FFFFFF"> Hinweis </font></td>
</tr>
</table>
</td>
<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
</tr>
</table>
<!-- Section -->
<a name="threadabbrechen"></a>
<h3>22.2.2 Abbrechen eines Threads </h3>
<p>
Zunächst einmal wird ein Thread dadurch beendet, dass das Ende
seiner <a href="index_r.html#ixb101108"><font color=#000080><tt>run</tt></font></a>-Methode
erreicht ist. In manchen Fällen ist es jedoch erforderlich, den
Thread von außen abzubrechen. Die bis zum JDK 1.1 übliche
Vorgehensweise bestand darin, die Methode <a name="ixa101472"><a href="index_s.html#ixb101115"><font color=#000080><tt>stop</tt></font></a></a>
der Klasse <a href="index_t.html#ixb100591"><font color=#000080><tt>Thread</tt></font></a>
aufzurufen. Dadurch wurde der Thread abgebrochen und aus der Liste
der aktiven Threads entfernt.
<p>
Wir wollen das vorige Beispiel erweitern und den Thread nach zwei
Sekunden durch Aufruf von <a href="index_s.html#ixb101115"><font color=#000080><tt>stop</tt></font></a>
beenden:
<a name="listingid022002"></a>
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
<tr>
<td valign=top>
<font color="#000055">
<pre>
<font color="#555555">001 </font><font color="#00AA00">/* Listing2202.java */</font>
<font color="#555555">002 </font>
<font color="#555555">003 </font><font color="#0000AA">class</font> MyThread2202
<font color="#555555">004 </font><font color="#0000AA">extends</font> Thread
<font color="#555555">005 </font>{
<font color="#555555">006 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> run()
<font color="#555555">007 </font> {
<font color="#555555">008 </font> <font color="#006699">int</font> i = 0;
<font color="#555555">009 </font> <font color="#0000AA">while</font> (<font color="#006699">true</font>) {
<font color="#555555">010 </font> System.out.println(i++);
<font color="#555555">011 </font> }
<font color="#555555">012 </font> }
<font color="#555555">013 </font>}
<font color="#555555">014 </font>
<font color="#555555">015 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Listing2202
<font color="#555555">016 </font>{
<font color="#555555">017 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
<font color="#555555">018 </font> {
<font color="#555555">019 </font> MyThread2202 t = <font color="#0000AA">new</font> MyThread2202();
<font color="#555555">020 </font> t.start();
<font color="#555555">021 </font> <font color="#0000AA">try</font> {
<font color="#555555">022 </font> Thread.sleep(2000);
<font color="#555555">023 </font> } <font color="#0000AA">catch</font> (InterruptedException e) {
<font color="#555555">024 </font> <font color="#00AA00">//nichts</font>
<font color="#555555">025 </font> }
<font color="#555555">026 </font> t.stop();
<font color="#555555">027 </font> }
<font color="#555555">028 </font>}</pre>
</font>
</td>
<td valign=top align=right>
<a href="../examples/Listing2202.java"><font color="#000055" size=-1>Listing2202.java</font></a></td>
</tr>
</table>
<i>
Listing 22.2: Beenden des Threads durch Aufruf von stop</i></p>
<p>
An diesem Beispiel kann man gut erkennen, dass der Thread tatsächlich
parallel zum Hauptprogramm ausgeführt wird. Nach dem Aufruf von
<a href="index_s.html#ixb101110"><font color=#000080><tt>start</tt></font></a>
beginnt einerseits die Zählschleife mit der Bildschirmausgabe,
aber gleichzeitig fährt das Hauptprogramm mit dem Aufruf der
<a href="index_s.html#ixb100855"><font color=#000080><tt>sleep</tt></font></a>-Methode
und dem Aufruf von <a href="index_s.html#ixb101115"><font color=#000080><tt>stop</tt></font></a>
fort. Beide Programmteile laufen also parallel ab.
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100%>
<tr>
<td width=1 align=left valign=top bgcolor="#FF9900"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=1></td>
<td width=1 align=left valign=top bgcolor="#FF9900"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top width=1000>
<p>
Mit dem JDK 1.2 wurde die Methode <a href="index_s.html#ixb101115"><font color=#000080><tt>stop</tt></font></a>
als <a name="ixa101473"><a href="index_d.html#ixb100161"><font color=#000080><tt>deprecated</tt></font></a></a>
markiert, d.h. sie sollte nicht mehr verwendet werden. Der Grund dafür
liegt in der potentiellen <i>Unsicherheit</i> des Aufrufs, denn es
ist nicht voraussagbar und auch nicht definiert, an welcher Stelle
ein Thread unterbrochen wird, wenn ein Aufruf von <a href="index_s.html#ixb101115"><font color=#000080><tt>stop</tt></font></a>
erfolgt. Es kann nämlich insbesondere vorkommen, dass der Abbruch
innerhalb eines kritischen Abschnitts erfolgt (der mit dem <a name="ixa101474"><a href="index_s.html#ixb100715"><font color=#000080><tt>synchronized</tt></font></a></a>-Schlüsselwort
geschützt wurde) oder in einer anwendungsspezifischen Transaktion
auftritt, die aus Konsistenzgründen nicht unterbrochen werden
darf.</td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top>
<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#FF9900">
<tr>
<td><font color="#FFFFFF"> JDK1.1-6.0 </font></td>
</tr>
</table>
</td>
<td width=1 align=left valign=top bgcolor="#FF9900"><img src="trp1_1.gif"></td>
</tr>
</table>
<p>
Die alternative Methode, einen Thread abzubrechen, besteht darin,
im Thread selbst auf Unterbrechungsanforderungen zu reagieren. So
könnte beispielsweise eine Membervariable <font color="#000077"><tt>cancelled</tt></font>
eingeführt und beim Initialisieren des Threads auf <a href="index_f.html#ixb100234"><font color=#000080><tt>false</tt></font></a>
gesetzt werden. Mit Hilfe einer Methode <font color="#000077"><tt>cancel</tt></font>
kann der Wert der Variable zu einem beliebigen Zeitpunkt auf <a href="index_t.html#ixb100233"><font color=#000080><tt>true</tt></font></a>
gesetzt werden. Aufgabe der Bearbeitungsroutine in <a href="index_r.html#ixb101108"><font color=#000080><tt>run</tt></font></a>
ist es nun, an geeigneten Stellen diese Variable abzufragen und für
den Fall, dass sie <a href="index_t.html#ixb100233"><font color=#000080><tt>true</tt></font></a>
ist, die Methode <a href="index_r.html#ixb101108"><font color=#000080><tt>run</tt></font></a>
konsistent zu beenden.
<p>
Dabei darf <font color="#000077"><tt>cancelled</tt></font> natürlich
nicht zu oft abgefragt werden, um das Programm nicht unnötig
aufzublähen und das Laufzeitverhalten des Threads nicht zu sehr
zu verschlechtern. Andererseits darf die Abfrage nicht zu selten erfolgen,
damit es nicht zu lange dauert, bis auf eine Abbruchanforderung reagiert
wird. Insbesondere darf es keine potentiellen Endlosschleifen geben,
in denen <font color="#000077"><tt>cancelled</tt></font> <i>überhaupt
nicht</i> abgefragt wird. Die Kunst besteht darin, diese gegensätzlichen
Anforderungen sinnvoll zu vereinen.
<p>
Glücklicherweise gibt es in der Klasse Thread bereits einige
Methoden, die einen solchen Mechanismus standardmäßig unterstützen:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
public void interrupt()
public boolean isInterrupted()
public static boolean interrupted()
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/lang/Thread.html" onClick="this.href=getApiDoc('java.lang.Thread')"><font color="#660066" size=-1>java.lang.Thread</font></a></td>
</tr>
</table>
<p>
Durch Aufruf von <a name="ixa101475"><a href="index_i.html#ixb101116"><font color=#000080><tt>interrupt</tt></font></a></a>
wird ein Flag gesetzt, das eine Unterbrechungsanforderung signalisiert.
Durch Aufruf von <a name="ixa101476"><a href="index_i.html#ixb101117"><font color=#000080><tt>isInterrupted</tt></font></a></a>
kann der Thread feststellen, ob das Abbruchflag gesetzt wurde und
der Thread beendet werden soll. Die statische Methode <a name="ixa101477"><a href="index_i.html#ixb101118"><font color=#000080><tt>interrupted</tt></font></a></a>
stellt den Status des Abbruchsflags beim <i>aktuellen</i> Thread fest.
Ihr Aufruf entspricht dem Aufruf von <font color="#000077"><tt>currentThread().isInterrupted()</tt></font>,
setzt aber zusätzlich das Abbruchflag auf seinen initialen Wert
<a href="index_f.html#ixb100234"><font color=#000080><tt>false</tt></font></a>
zurück.
<p>
Wir wollen uns den Gebrauch dieser Methoden an einem Beispiel ansehen.
Dazu soll ein Programm geschrieben werden, das in einem separaten
Thread ununterbrochen Textzeilen auf dem Bildschirm ausgibt. Das Hauptprogramm
soll den Thread erzeugen und nach 2 Sekunden durch einen Aufruf von
<a href="index_i.html#ixb101116"><font color=#000080><tt>interrupt</tt></font></a>
eine Unterbrechungsanforderung erzeugen. Der Thread soll dann die
aktuelle Zeile fertig ausgeben und anschließend terminieren.
<a name="listingid022003"></a>
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
<tr>
<td valign=top>
<font color="#000055">
<pre>
<font color="#555555">001 </font><font color="#00AA00">/* Listing2203.java */</font>
<font color="#555555">002 </font>
<font color="#555555">003 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Listing2203
<font color="#555555">004 </font><font color="#0000AA">extends</font> Thread
<font color="#555555">005 </font>{
<font color="#555555">006 </font> <font color="#006699">int</font> cnt = 0;
<font color="#555555">007 </font>
<font color="#555555">008 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> run()
<font color="#555555">009 </font> {
<font color="#555555">010 </font> <font color="#0000AA">while</font> (<font color="#006699">true</font>) {
<font color="#555555">011 </font> <font color="#0000AA">if</font> (isInterrupted()) {
<font color="#555555">012 </font> <font color="#0000AA">break</font>;
<font color="#555555">013 </font> }
<font color="#555555">014 </font> printLine(++cnt);
<font color="#555555">015 </font> }
<font color="#555555">016 </font> }
<font color="#555555">017 </font>
<font color="#555555">018 </font> <font color="#0000AA">private</font> <font color="#006699">void</font> printLine(<font color="#006699">int</font> cnt)
<font color="#555555">019 </font> {
<font color="#555555">020 </font> <font color="#00AA00">//Zeile ausgeben</font>
<font color="#555555">021 </font> System.out.print(cnt + <font color="#0000FF">": "</font>);
<font color="#555555">022 </font> <font color="#0000AA">for</font> (<font color="#006699">int</font> i = 0; i < 30; ++i) {
<font color="#555555">023 </font> System.out.print(i == cnt % 30 ? <font color="#0000FF">"* "</font> : <font color="#0000FF">". "</font>);
<font color="#555555">024 </font> }
<font color="#555555">025 </font> System.out.println();
<font color="#555555">026 </font> <font color="#00AA00">//100 ms. warten</font>
<font color="#555555">027 </font> <font color="#0000AA">try</font> {
<font color="#555555">028 </font> Thread.sleep(100);
<font color="#555555">029 </font> } <font color="#0000AA">catch</font> (InterruptedException e) {
<font color="#555555">030 </font> interrupt();
<font color="#555555">031 </font> }
<font color="#555555">032 </font> }
<font color="#555555">033 </font>
<font color="#555555">034 </font> <font color="#0000AA">public</font> <font color="#0000AA">static</font> <font color="#006699">void</font> main(String[] args)
<font color="#555555">035 </font> {
<font color="#555555">036 </font> Listing2203 th = <font color="#0000AA">new</font> Listing2203();
<font color="#555555">037 </font> {
<font color="#555555">038 </font> <font color="#00AA00">//Thread starten</font>
<font color="#555555">039 </font> th.start();
<font color="#555555">040 </font> <font color="#00AA00">//2 Sekunden warten</font>
<font color="#555555">041 </font> <font color="#0000AA">try</font> {
<font color="#555555">042 </font> Thread.sleep(2000);
<font color="#555555">043 </font> } <font color="#0000AA">catch</font> (InterruptedException e) {
<font color="#555555">044 </font> }
<font color="#555555">045 </font> <font color="#00AA00">//Thread unterbrechen</font>
<font color="#555555">046 </font> th.interrupt();
<font color="#555555">047 </font> }
<font color="#555555">048 </font> }
<font color="#555555">049 </font>}</pre>
</font>
</td>
<td valign=top align=right>
<a href="../examples/Listing2203.java"><font color="#000055" size=-1>Listing2203.java</font></a></td>
</tr>
</table>
<i>
Listing 22.3: Anwendung der Methoden interrupt und isInterrupted</i></p>
<p>
Die <a href="index_m.html#ixb100150"><font color=#000080><tt>main</tt></font></a>-Methode
ist leicht zu verstehen. Sie startet den Thread, wartet 2 Sekunden
und ruft dann die Methode <a href="index_i.html#ixb101116"><font color=#000080><tt>interrupt</tt></font></a>
auf. In der Methode <a href="index_r.html#ixb101108"><font color=#000080><tt>run</tt></font></a>
wird in einer Endlosschleife durch Aufruf von <font color="#000077"><tt>printLine</tt></font>
jeweils eine neue Zeile ausgegeben. Zuvor wird bei jedem Aufruf mit
<a href="index_i.html#ixb101117"><font color=#000080><tt>isInterrupted</tt></font></a>
geprüft, ob das Abbruchflag gesetzt wurde. Ist das der Fall,
wird keine weitere Zeile ausgegeben, sondern die Schleife (und mit
ihr der Thread) beendet.
<p>
Innerhalb von <font color="#000077"><tt>printLine</tt></font> wird
zunächst die Textzeile ausgegeben und dann eine Pause von 100
Millisekunden eingelegt. Da in der Methode keine Abfrage des Abbruchflags
erfolgt, ist sichergestellt, dass die aktuelle Zeile selbst dann bis
zum Ende ausgegeben wird, wenn der Aufruf von <a href="index_i.html#ixb101116"><font color=#000080><tt>interrupt</tt></font></a>
mitten in der Schleife zur Ausgabe der Bildschirmzeile erfolgt.
<p>
Da die Pause nach der Bildschirmausgabe mit 100 Millisekunden vermutlich
länger dauert als die Bildschirmausgabe selbst, ist es recht
wahrscheinlich, dass der Aufruf von <a href="index_i.html#ixb101116"><font color=#000080><tt>interrupt</tt></font></a>
während des Aufrufs von <a href="index_s.html#ixb100855"><font color=#000080><tt>sleep</tt></font></a>
erfolgt. Ist das der Fall, wird <a href="index_s.html#ixb100855"><font color=#000080><tt>sleep</tt></font></a>
mit einer <a href="index_i.html#ixb100628"><font color=#000080><tt>InterruptedException</tt></font></a>
abgebrochen (auch wenn die geforderte Zeitspanne noch nicht vollständig
verstrichen ist). Wichtig ist hier, dass das Abbruchflag zurückgesetzt
wird und der Aufruf von <a href="index_i.html#ixb101116"><font color=#000080><tt>interrupt</tt></font></a>
somit eigentlich verlorengehen würde, wenn er nicht direkt in
der <a href="index_c.html#ixb100570"><font color=#000080><tt>catch</tt></font></a>-Klausel
behandelt würde. Wir rufen daher innerhalb der <a href="index_c.html#ixb100570"><font color=#000080><tt>catch</tt></font></a>-Klausel
<a href="index_i.html#ixb101116"><font color=#000080><tt>interrupt</tt></font></a>
erneut auf, um das Flag wieder zu setzen und <a href="index_r.html#ixb101108"><font color=#000080><tt>run</tt></font></a>
die Abbruchanforderung zu signalisieren. Alternativ hätten wir
auch die Ausnahme an den Aufrufer weitergeben können und sie
dort als Auslöser für das Ende der Ausgabeschleife betrachten
können.
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100%>
<tr>
<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top width=1000>
<p>
Die beiden anderen Methoden, die eine Ausnahme des Typs <a name="ixa101478"><a href="index_i.html#ixb100628"><font color=#000080><tt>InterruptedException</tt></font></a></a>
auslösen können, sind <a name="ixa101479"><a href="index_j.html#ixb101119"><font color=#000080><tt>join</tt></font></a></a>
der Klasse <a href="index_t.html#ixb100591"><font color=#000080><tt>Thread</tt></font></a>
und <a name="ixa101480"><a href="index_w.html#ixb101120"><font color=#000080><tt>wait</tt></font></a></a>
der Klasse <a href="index_o.html#ixb100224"><font color=#000080><tt>Object</tt></font></a>.
Auch sie setzen beim Auftreten der Ausnahme das Abbruchflag zurück
und müssen daher in ähnlicher Weise behandelt werden.</td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top>
<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
<tr>
<td><font color="#FFFFFF"> Hinweis </font></td>
</tr>
</table>
</td>
<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
</tr>
</table>
<!-- Section -->
<a name="sectlevel3id022002003"></a>
<h3>22.2.3 <a name="ixa101481">Anhalten eines Threads</a></h3>
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100%>
<tr>
<td width=1 align=left valign=top bgcolor="#FF9900"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=1></td>
<td width=1 align=left valign=top bgcolor="#FF9900"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top width=1000>
<p>
Die Klasse <a href="index_t.html#ixb100591"><font color=#000080><tt>Thread</tt></font></a>
besitzt zwei Methoden <a name="ixa101482"><a href="index_s.html#ixb101122"><font color=#000080><tt>suspend</tt></font></a></a>
und <a name="ixa101483"><a href="index_r.html#ixb101123"><font color=#000080><tt>resume</tt></font></a></a>,
mit deren Hilfe es möglich ist, einen Thread vorübergehend
anzuhalten und anschließend an der Unterbrechungsstelle fortzusetzen.
Beide Methoden sind nicht ganz ungefährlich und können unbemerkt
Deadlocks verursachen. Sie wurden daher mit dem JDK 1.2 als <a name="ixa101484"><a href="index_d.html#ixb100161"><font color=#000080><tt>deprecated</tt></font></a></a>
markiert und sollten nicht mehr verwendet werden. Ihre Funktionalität
muss - wenn erforderlich - manuell nachgebildet werden.</td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top>
<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#FF9900">
<tr>
<td><font color="#FFFFFF"> JDK1.1-6.0 </font></td>
</tr>
</table>
</td>
<td width=1 align=left valign=top bgcolor="#FF9900"><img src="trp1_1.gif"></td>
</tr>
</table>
<!-- Section -->
<a name="weiterethreadmethoden"></a>
<h3>22.2.4 Weitere Methoden </h3>
<!-- Section -->
<a name="sectlevel4id022002004001"></a>
<h4>sleep </h4>
<p>
Sowohl innerhalb der Threads als auch innerhalb der Methode <a href="index_m.html#ixb100150"><font color=#000080><tt>main</tt></font></a>
wird ein Aufruf von <font color="#000077"><tt>Thread.sleep</tt></font>
verwendet, um das Programm pausieren zu lassen. <a name="ixa101485"><a href="index_s.html#ixb100855"><font color=#000080><tt>sleep</tt></font></a></a>
ist eine statische Methode der Klasse <a href="index_t.html#ixb100591"><font color=#000080><tt>Thread</tt></font></a>,
die mit einem oder zwei Parametern aufgerufen werden kann:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
public static void sleep(long millis)
public static void sleep(long millis, int nanos)
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/lang/Thread.html" onClick="this.href=getApiDoc('java.lang.Thread')"><font color="#660066" size=-1>java.lang.Thread</font></a></td>
</tr>
</table>
<p>
Die erste Version sorgt dafür, dass der aktuelle prozess für
die (in Millisekunden angegebene) Zeit unterbrochen wird. Die zweite
erlaubt eine noch genauere Eingabe der Wartezeit, indem auch Bruchteile
im Nanosekundenbereich angegeben werden können. In beiden Fällen
wird die tatsächlich erzielbare Genauigkeit allerdings durch
Hardwarerestriktionen der Zielmaschine begrenzt. Im Falle der aktuellen
SUN-JDKs unter Windows liegt sie bei etwa 1 ms und ist damit wesentlich
höher als <a href="index_c.html#ixb100854"><font color=#000080><tt>currentTimeMillis</tt></font></a>.
In <a href="k100110.html#currenttimemillis">Abschnitt 16.3.5</a> finden
sich Beispielprogramme, mit denen die Auflösungen von <a href="index_c.html#ixb100854"><font color=#000080><tt>currentTimeMillis</tt></font></a>
und <a href="index_s.html#ixb100855"><font color=#000080><tt>sleep</tt></font></a>
ermittelt werden können.
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100%>
<tr>
<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top width=1000>
<p>
Die Kapselung des Aufrufs von <font color="#000077"><tt>Thread.sleep</tt></font>
innerhalb eines <font color="#000077"><tt>try-catch</tt></font>-Blocks
ist erforderlich, weil <a href="index_s.html#ixb100855"><font color=#000080><tt>sleep</tt></font></a>
während der Wartezeit eine Ausnahme vom Typ <a href="index_i.html#ixb100628"><font color=#000080><tt>InterruptedException</tt></font></a>
auslösen kann. Ohne den <font color="#000077"><tt>try-catch</tt></font>-Block
würde diese an den Aufrufer weitergegeben werden.</td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top>
<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
<tr>
<td><font color="#FFFFFF"> Hinweis </font></td>
</tr>
</table>
</td>
<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
</tr>
</table>
<p>
Als Klassenmethode kann <a href="index_s.html#ixb100855"><font color=#000080><tt>sleep</tt></font></a>
aufgerufen werden, ohne dass eine Instanz der Klasse <a href="index_t.html#ixb100591"><font color=#000080><tt>Thread</tt></font></a>
verfügbar ist. Insbesondere kann die Methode auch dazu verwendet
werden, das Hauptprogramm pausieren zu lassen, das ja nicht explizit
als Thread erzeugt wurde. Dies funktioniert deshalb, weil beim Starten
eines Java-Programms automatisch ein Thread für die Ausführung
des Hauptprogramms angelegt wurde.
<!-- Section -->
<a name="sectlevel4id022002004002"></a>
<h4>isAlive<a name="ixa101486"></a> </h4>
<p>
Mit dieser Methode kann festgestellt werden, ob ein Thread noch läuft.
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
public final boolean isAlive()
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/lang/Thread.html" onClick="this.href=getApiDoc('java.lang.Thread')"><font color="#660066" size=-1>java.lang.Thread</font></a></td>
</tr>
</table>
<p>
<a name="ixa101486"><a href="index_i.html#ixb101124"><font color=#000080><tt>isAlive</tt></font></a></a>
gibt immer dann <a href="index_t.html#ixb100233"><font color=#000080><tt>true</tt></font></a>
zurück, wenn der Thread gestartet, aber noch nicht wieder beendet
wurde. Beendet wird ein Thread, wenn das Ende der <a name="ixa101487"><a href="index_r.html#ixb101108"><font color=#000080><tt>run</tt></font></a></a>-Methode
erreicht ist oder wenn (in Prä-1.2-JDKs) die Methode <a href="index_s.html#ixb101115"><font color=#000080><tt>stop</tt></font></a>
aufgerufen wurde.
<!-- Section -->
<a name="sectlevel4id022002004003"></a>
<h4>join </h4>
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
public final void join()
throws InterruptedException
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/lang/Thread.html" onClick="this.href=getApiDoc('java.lang.Thread')"><font color="#660066" size=-1>java.lang.Thread</font></a></td>
</tr>
</table>
<p>
Die Methode <a name="ixa101488"><a href="index_j.html#ixb101119"><font color=#000080><tt>join</tt></font></a></a>
wartet auf das Ende des Threads, für den sie aufgerufen wurde.
Sie ermöglicht es damit, einen prozess zu starten und (ähnlich
einem Funktionsaufruf) mit der weiteren Ausführung so lange zu
warten, bis der prozess beendet ist. <a href="index_j.html#ixb101119"><font color=#000080><tt>join</tt></font></a>
gibt es auch mit einem <a href="index_l.html#ixb100245"><font color=#000080><tt>long</tt></font></a>
als Parameter. In diesem Fall wartet die Methode maximal die angegebene
Zeit in Millisekunden und fährt nach Ablauf der Zeit auch dann
fort, wenn der prozess noch nicht beendet ist.
<hr>
<table border=0 cellpadding=0 cellspacing=1 width="100%">
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html"> Titel </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html"> Inhalt </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html"> Suchen </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html"> Index </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()"> DOC </a>
<td align="right">Handbuch der Java-Programmierung, 5. Auflage, Addison
Wesley, Version 5.0.1
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100143.html"> << </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100144.html"> < </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100146.html"> > </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100150.html"> >> </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()"> API </a>
<td align="right">© 1998, 2007 Guido Krüger & Thomas
Stark, <a href="http://www.javabuch.de">http://www.javabuch.de</a>
</table>
<a name="endofbody"></a>
</body>
</html>
|