diff options
| author | Sven Eisenhauer <sven@sven-eisenhauer.net> | 2023-11-10 15:11:48 +0100 |
|---|---|---|
| committer | Sven Eisenhauer <sven@sven-eisenhauer.net> | 2023-11-10 15:11:48 +0100 |
| commit | 33613a85afc4b1481367fbe92a17ee59c240250b (patch) | |
| tree | 670b842326116b376b505ec2263878912fca97e2 /Master/Reference Architectures and Patterns/hjp5/html/k100145.html | |
| download | Studium-master.tar.gz Studium-master.tar.bz2 | |
Diffstat (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100145.html')
| -rw-r--r-- | Master/Reference Architectures and Patterns/hjp5/html/k100145.html | 692 |
1 files changed, 692 insertions, 0 deletions
diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100145.html b/Master/Reference Architectures and Patterns/hjp5/html/k100145.html new file mode 100644 index 0000000..ea6ff51 --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100145.html @@ -0,0 +1,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>
|
