So wie Menschen geboren, alt, krank und sterben, müssen auch Threads vier verschiedene Zustände durchlaufen: Starten (Warten), Laufen, Anhalten und Stoppen. Diese vier Zustände können durch Methoden in der Thread-Klasse gesteuert werden. Die Methoden, die sich auf diese vier Zustände in der Thread-Klasse beziehen, sind unten aufgeführt.
// 开始线程 public void start( ); public void run( ); // 挂起和唤醒线程 public void resume( ); // 不建议使用 public void suspend( ); // 不建议使用 public static void sleep(long millis); public static void sleep(long millis, int nanos); // 终止线程 public void stop( ); // 不建议使用 public void interrupt( ); // 得到线程状态 public boolean isAlive( ); public boolean isInterrupted( ); public static boolean interrupted( ); // join方法 public void join( ) throws InterruptedException;
1. Erstellen Sie den Thread und führen Sie ihn aus
Der Thread führt den Code in der Ausführungsmethode nicht sofort nach seiner Einrichtung aus, sondern führt ihn aus in einem Wartezustand. Wenn sich der Thread im Wartezustand befindet, können Sie über die Methoden der Thread-Klasse verschiedene Attribute des Threads festlegen, z. B. die Priorität des Threads (setPriority), den Thread-Namen (setName) und den Thread-Typ (setDaemon).
Wenn die Startmethode aufgerufen wird, beginnt der Thread mit der Ausführung des Codes in der Run-Methode. Der Thread wechselt in den laufenden Zustand. Sie können die isAlive-Methode der Thread-Klasse verwenden, um festzustellen, ob der Thread ausgeführt wird. Wenn sich der Thread im laufenden Zustand befindet, gibt isAlive „true“ zurück. Wenn isAlive „false“ zurückgibt, befindet sich der Thread möglicherweise im Wartezustand oder im gestoppten Zustand. Der folgende Code demonstriert den Wechsel zwischen den drei Zuständen Thread-Erstellung, Ausführung und Stopp und gibt den entsprechenden isAlive-Rückgabewert aus.
package chapter2; public class LifeCycle extends Thread { public void run() { int n = 0; while ((++n) < 1000); } public static void main(String[] args) throws Exception { LifeCycle thread1 = new LifeCycle(); System.out.println("isAlive: " + thread1.isAlive()); thread1.start(); System.out.println("isAlive: " + thread1.isAlive()); thread1.join(); // 等线程thread1结束后再继续执行 System.out.println("thread1已经结束!"); System.out.println("isAlive: " + thread1.isAlive()); } }
Bitte beachten Sie, dass im obigen Code die Join-Methode verwendet wird. Die Hauptfunktion dieser Methode besteht darin, sicherzustellen, dass das Programm nach Abschluss der Ausführungsmethode des Threads weiter ausgeführt wird in einem späteren Artikel.
Das Ergebnis der Ausführung des obigen Codes:
isAlive: false isAlive: true thread1已经结束! isAlive: false
2. Threads anhalten und aktivieren
Sobald der Thread mit der Ausführung der Ausführungsmethode beginnt, wird er erst beendet, wenn die Ausführungsmethode abgeschlossen ist. Während der Ausführung des Threads können Sie die Thread-Ausführung jedoch über zwei Methoden vorübergehend stoppen. Diese beiden Methoden sind Suspend und Sleep. Nachdem Sie den Thread mit Suspend angehalten haben, können Sie den Thread über die Resume-Methode aktivieren. Nachdem Sie Sleep verwendet haben, um den Thread in den Ruhezustand zu versetzen, kann sich der Thread erst nach der festgelegten Zeit im Bereitschaftszustand befinden (nachdem der Thread-Ruhezustand endet, wird der Thread möglicherweise nicht sofort ausgeführt, sondern wechselt nur in den Bereitschaftszustand und wartet auf die Planung durch das System). .
Obwohl Suspend und Resume Threads leicht anhalten und aufwecken können, kann die Verwendung dieser beiden Methoden dazu führen, dass einige unvorhersehbare Dinge passieren. Daher werden diese beiden Methoden als veraltet (Protest) markiert, was darauf hinweist, dass diese beiden Methoden in zukünftigen JDKs gelöscht werden könnten Versuchen Sie daher, diese beiden Methoden nicht zum Betreiben von Threads zu verwenden. Der folgende Code demonstriert die Verwendung der Sleep-, Suspend- und Resume-Methoden.
package chapter2; public class MyThread extends Thread { class SleepThread extends Thread { public void run() { try { sleep(2000); } catch (Exception e) { } } } public void run() { while (true) System.out.println(new java.util.Date().getTime()); } public static void main(String[] args) throws Exception { MyThread thread = new MyThread(); SleepThread sleepThread = thread.new SleepThread(); sleepThread.start(); // 开始运行线程sleepThread sleepThread.join(); // 使线程sleepThread延迟2秒 thread.start(); boolean flag = false; while (true) { sleep(5000); // 使主线程延迟5秒 flag = !flag; if (flag) thread.suspend(); else thread.resume(); } } }
Oberflächlich betrachtet sind die Auswirkungen der Verwendung von Sleep und Suspend ähnlich, aber die Sleep-Methode ist nicht gleichbedeutend mit Suspend. Der größte Unterschied zwischen ihnen besteht darin, dass sie in einem Thread über Suspend verwendet werden kann Methode: Einen anderen Thread anhalten. Im obigen Code wird der Thread beispielsweise im Hauptthread angehalten. Sleep funktioniert nur für den aktuell ausgeführten Thread. Im obigen Code schlafen sleepThread und der Hauptthread 2 Sekunden bzw. 5 Sekunden lang. Beachten Sie bei der Verwendung von Sleep, dass Sie nicht einen Thread in einem anderen Thread in den Ruhezustand versetzen können. Beispielsweise kann die Verwendung der Methode thread.sleep (2000) in der Hauptmethode den Thread-Thread nicht für 2 Sekunden in den Ruhezustand versetzen, sondern nur den Haupt-Thread für 2 Sekunden in den Ruhezustand versetzen.
Bei der Anwendung der Schlafmethode sind zwei Punkte zu beachten:
1. Die Schlafmethode hat zwei überladene Formen, von denen eine nicht nur Millisekunden, sondern auch Nanosekunden festlegen kann (1.000.000 Nanosekunden entsprechen 1 Millisekunde). Allerdings ist die Java Virtual Machine auf den meisten Betriebssystemplattformen nicht auf Nanosekunden genau. Wenn daher Nanosekunden für den Ruhezustand eingestellt sind, verwendet die Java Virtual Machine die Millisekunde, die diesem Wert am nächsten kommt.
2. Wenn Sie die Sleep-Methode verwenden, müssen Sie throws oder try{...}catch{...} verwenden. Da die run-Methode keine throws verwenden kann, können Sie nur try{...}catch{...} verwenden Wenn der Thread schläft, löst Sleep eine InterruptedException aus, wenn ein Thread mithilfe der Interrupt-Methode unterbrochen wird (diese Methode wird in 2.3.3 erläutert). Die Schlafmethode ist wie folgt definiert:
1 public static void sleep(long millis) throws InterruptedException 2 public static void sleep(long millis, int nanos) throws InterruptedException
3. Drei Möglichkeiten, einen Thread zu beenden
Es gibt drei Möglichkeiten, einen Thread zu beenden.
1. Verwenden Sie das Exit-Flag, um den Thread normal zu beenden, dh der Thread wird beendet, wenn die Ausführungsmethode abgeschlossen ist.
2. Verwenden Sie die Stop-Methode, um den Thread zwangsweise zu beenden (diese Methode wird nicht empfohlen, da Stop, ebenso wie Suspend und Resume, ebenfalls zu unvorhersehbaren Ergebnissen führen kann).
3. Verwenden Sie die Interrupt-Methode, um den Thread zu unterbrechen.
1. Beenden Sie den Thread mit dem Exit-Flag
当run方法执行完后,线程就会退出。但有时run方法是永远不会结束的。如在服务端程序中使用线程进行监听客户端请求,或是其他的需要循环处理的任务。在这种情况下,一般是将这些任务放在一个循环中,如while循环。如果想让循环永远运行下去,可以使用while(true){……}来处理。但要想使while循环在某一特定条件下退出,最直接的方法就是设一个boolean类型的标志,并通过设置这个标志为true或false来控制while循环是否退出。下面给出了一个利用退出标志终止线程的例子。
package chapter2; public class ThreadFlag extends Thread { public volatile boolean exit = false; public void run() { while (!exit); } public static void main(String[] args) throws Exception { ThreadFlag thread = new ThreadFlag(); thread.start(); sleep(5000); // 主线程延迟5秒 thread.exit = true; // 终止线程thread thread.join(); System.out.println("线程退出!"); } }
在上面代码中定义了一个退出标志exit,当exit为true时,while循环退出,exit的默认值为false.在定义exit时,使用了一个Java关键字volatile,这个关键字的目的是使exit同步,也就是说在同一时刻只能由一个线程来修改exit的值,
2. 使用stop方法终止线程
使用stop方法可以强行终止正在运行或挂起的线程。我们可以使用如下的代码来终止线程:
1 thread.stop();
虽然使用上面的代码可以终止线程,但使用stop方法是很危险的,就象突然关闭计算机电源,而不是按正常程序关机一样,可能会产生不可预料的结果,因此,并不推荐使用stop方法来终止线程。
3. 使用interrupt方法终止线程
使用interrupt方法来终端线程可分为两种情况:
(1)线程处于阻塞状态,如使用了sleep方法。
(2)使用while(!isInterrupted()){……}来判断线程是否被中断。
在第一种情况下使用interrupt方法,sleep方法将抛出一个InterruptedException例外,而在第二种情况下线程将直接退出。下面的代码演示了在第一种情况下使用interrupt方法。
package chapter2; public class ThreadInterrupt extends Thread { public void run() { try { sleep(50000); // 延迟50秒 } catch (InterruptedException e) { System.out.println(e.getMessage()); } } public static void main(String[] args) throws Exception { Thread thread = new ThreadInterrupt(); thread.start(); System.out.println("在50秒之内按任意键中断线程!"); System.in.read(); thread.interrupt(); thread.join(); System.out.println("线程已经退出!"); } }
上面代码的运行结果如下:
在50秒之内按任意键中断线程! sleep interrupted 线程已经退出!
在调用interrupt方法后, sleep方法抛出异常,然后输出错误信息:sleep interrupted.
注意:在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他线程是否被中断。因此,while (!isInterrupted())也可以换成while (!Thread.interrupted())。
以上就是java线程之线程的生命周期的使用的内容,更多相关内容请关注PHP中文网(www.php.cn)!