程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java多線程編程之線程的性命周期

java多線程編程之線程的性命周期

編輯:關於JAVA

java多線程編程之線程的性命周期。本站提示廣大學習愛好者:(java多線程編程之線程的性命周期)文章只能為提供參考,不一定能成為您想要的結果。以下是java多線程編程之線程的性命周期正文



// 開端線程
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、創立並運轉線程

線程在樹立後其實不立時履行run辦法中的代碼,而是處於期待狀況。線程處於期待狀況時,可以經由過程Thread類的辦法來設置線程不各類屬性,如線程的優先級(setPriority)、線程名(setName)和線程的類型(setDaemon)等。
當挪用start辦法後,線程開端履行run辦法中的代碼。線程進入運轉狀況。可以經由過程Thread類的isAlive辦法來斷定線程能否處於運轉狀況。當線程處於運轉狀況時,isAlive前往true,當isAlive前往false時,能夠線程處於期待狀況,也能夠處於停滯狀況。上面的代碼演示了線程的創立、運轉和停滯三個狀況之間的切換,並輸入了響應的isAlive前往值。

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());
}
}

要留意一下,在下面的代碼中應用了join辦法,這個辦法的重要功效是包管線程的run辦法完成後法式才持續運轉,這個辦法將在前面的文章中引見
下面代碼的運轉成果:
isAlive: false
isAlive: true
thread1曾經停止!
isAlive: false

2、掛起和叫醒線程

一但線程開端履行run辦法,就會一向到這個run辦法履行完成這個線程才加入。但在線程履行的進程中,可以經由過程兩個辦法使線程臨時停滯履行。這兩個辦法是suspend和sleep。在應用suspend掛起線程後,可以經由過程resume辦法叫醒線程。而應用sleep使線程休眠後,只能在設定的時光後使線程處於停當狀況(在線程休眠停止後,線程紛歧定會立時履行,只是進入了停當狀況,期待著體系停止調劑)。
固然suspend和resume可以很便利地使線程掛起和叫醒,但因為應用這兩個辦法能夠會形成一些弗成預感的工作產生,是以,這兩個辦法被標識為deprecated(抗議)標志,這注解在今後的jdk版本中這兩個辦法能夠被刪除,所以盡可能不要應用這兩個辦法來操作線程。上面的代碼演示了sleep、suspend和resume三個辦法的應用。

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();
}
}
}

從外面上看,應用sleep和suspend所發生的後果相似,但sleep辦法其實不同等於suspend。它們之間最年夜的一個差別是可以在一個線程中經由過程suspend辦法來掛起別的一個線程,如下面代碼中在主線程中掛起了thread線程。而sleep只對以後正在履行的線程起感化。在下面代碼平分別使sleepThread和主線程休眠了2秒和5秒。在應用sleep時要留意,不克不及在一個線程中來休眠另外一個線程。如main辦法中應用thread.sleep(2000)辦法是沒法使thread線程休眠2秒的,而只能使主線程休眠2秒。
在應用sleep辦法時有兩點須要留意:
1. sleep辦法有兩個重載情勢,個中一個重載情勢不只可以設毫秒,並且還可以設納秒(1,000,000納秒等於1毫秒)。但年夜多半操作體系平台上的Java虛擬機都沒法准確到納秒,是以,假如對sleep設置了納秒,Java虛擬機將取最接近這個值的毫秒。
2. 在應用sleep辦法時必需應用throws或try{...}catch{...}。由於run辦法沒法應用throws,所以只能應用try{...}catch{...}。當在線程休眠的進程中,應用interrupt辦法(這個辦法將在2.3.3中評論辯論)中止線程時sleep會拋出一個InterruptedException異常。sleep辦法的界說以下:

public static void sleep(long millis)  throws InterruptedException
public static void sleep(long millis,  int nanos)  throws InterruptedException

3、終止線程的三種辦法

有三種辦法可使終止線程。
1.  應用加入標記,使線程正常加入,也就是當run辦法完成後線程終止。
2.  應用stop辦法強行終止線程(這個辦法不推舉應用,由於stop和suspend、resume一樣,也能夠產生弗成預感的成果)。
3.  應用interrupt辦法中止線程。
1. 應用加入標記終止線程
當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辦法可以強行終止正在運轉或掛起的線程。我們可使用以下的代碼來終止線程:
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())。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved