日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
初學(xué)Java多線程:線程的生命周期

與人有生老病死一樣,線程也同樣要經(jīng)歷開始(等待)、運(yùn)行、掛起和停止四種不同的狀態(tài)。這四種狀態(tài)都可以通過Thread類中的方法進(jìn)行控制。下面給出了Thread類中和這四種狀態(tài)相關(guān)的方法。

成都創(chuàng)新互聯(lián)長期為上千多家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為懷安企業(yè)提供專業(yè)的網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站建設(shè),懷安網(wǎng)站改版等技術(shù)服務(wù)。擁有十載豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

 
 
 
  1. // 開始線程  
  2. public void start( );  
  3. public void run( );  
  4.  
  5. // 掛起和喚醒線程  
  6. public void resume( );     // 不建議使用  
  7. public void suspend( );    // 不建議使用  
  8. public static void sleep(long millis);  
  9. public static void sleep(long millis, int nanos);  
  10.  
  11. // 終止線程  
  12. public void stop( );       // 不建議使用  
  13. public void interrupt( );  
  14.  
  15. // 得到線程狀態(tài)  
  16. public boolean isAlive( );  
  17. public boolean isInterrupted( );  
  18. public static boolean interrupted( );  
  19.  
  20. // join方法  
  21. public void join( ) throws InterruptedException;  

一、創(chuàng)建并運(yùn)行線程

線程在建立后并不馬上執(zhí)行run方法中的代碼,而是處于等待狀態(tài)。線程處于等待狀態(tài)時(shí),可以通過Thread類的方法來設(shè)置線程不各種屬性,如線程的優(yōu)先級(setPriority)、線程名(setName)和線程的類型(setDaemon)等。

當(dāng)調(diào)用start方法后,線程開始執(zhí)行run方法中的代碼。線程進(jìn)入運(yùn)行狀態(tài)??梢酝ㄟ^Thread類的isAlive方法來判斷線程是否處于運(yùn)行狀態(tài)。當(dāng)線程處于運(yùn)行狀態(tài)時(shí),isAlive返回true,當(dāng)isAlive返回false時(shí),可能線程處于等待狀態(tài),也可能處于停止?fàn)顟B(tài)。下面的代碼演示了線程的創(chuàng)建、運(yùn)行和停止三個(gè)狀態(tài)之間的切換,并輸出了相應(yīng)的isAlive返回值。

 
 
 
  1. package chapter2;  
  2.  
  3. public class LifeCycle extends Thread  
  4. {  
  5.     public void run()  
  6.     {  
  7.         int n = 0;  
  8.         while ((++n) < 1000);          
  9.     }  
  10.        
  11.     public static void main(String[] args) throws Exception  
  12.     {  
  13.         LifeCycle thread1 = new LifeCycle();  
  14.         System.out.println("isAlive: " + thread1.isAlive());  
  15.         thread1.start();  
  16.         System.out.println("isAlive: " + thread1.isAlive());  
  17.         thread1.join();  // 等線程thread1結(jié)束后再繼續(xù)執(zhí)行   
  18.         System.out.println("thread1已經(jīng)結(jié)束!");  
  19.         System.out.println("isAlive: " + thread1.isAlive());  
  20.     }  
  21. }  

要注意一下,在上面的代碼中使用了join方法,這個(gè)方法的主要功能是保證線程的run方法完成后程序才繼續(xù)運(yùn)行,這個(gè)方法將在后面的文章中介紹

上面代碼的運(yùn)行結(jié)果:

isAlive: false
isAlive: true
thread1已經(jīng)結(jié)束!
isAlive: false

二、掛起和喚醒線程

一但線程開始執(zhí)行run方法,就會一直到這個(gè)run方法執(zhí)行完成這個(gè)線程才退出。但在線程執(zhí)行的過程中,可以通過兩個(gè)方法使線程暫時(shí)停止執(zhí)行。這兩個(gè)方法是suspend和sleep。在使用suspend掛起線程后,可以通過resume方法喚醒線程。而使用sleep使線程休眠后,只能在設(shè)定的時(shí)間后使線程處于就緒狀態(tài)(在線程休眠結(jié)束后,線程不一定會馬上執(zhí)行,只是進(jìn)入了就緒狀態(tài),等待著系統(tǒng)進(jìn)行調(diào)度)。

雖然suspend和resume可以很方便地使線程掛起和喚醒,但由于使用這兩個(gè)方法可能會造成一些不可預(yù)料的事情發(fā)生,因此,這兩個(gè)方法被標(biāo)識為deprecated(抗議)標(biāo)記,這表明在以后的jdk版本中這兩個(gè)方法可能被刪除,所以盡量不要使用這兩個(gè)方法來操作線程。下面的代碼演示了sleep、suspend和resume三個(gè)方法的使用。

 
 
 
  1. package chapter2;  
  2.  
  3. public class MyThread extends Thread  
  4. {  
  5.     class SleepThread extends Thread  
  6.     {  
  7.         public void run()  
  8.         {  
  9.             try 
  10.             {  
  11.                 sleep(2000);  
  12.             }  
  13.             catch (Exception e)  
  14.             {  
  15.             }  
  16.         }  
  17.     }  
  18.     public void run()  
  19.     {  
  20.         while (true)  
  21.             System.out.println(new java.util.Date().getTime());  
  22.     }  
  23.     public static void main(String[] args) throws Exception  
  24.     {  
  25.         MyThread thread = new MyThread();  
  26.         SleepThread sleepThread = thread.new SleepThread();  
  27.         sleepThread.start(); // 開始運(yùn)行線程sleepThread  
  28.         sleepThread.join();  // 使線程sleepThread延遲2秒  
  29.         thread.start();  
  30.         boolean flag = false;  
  31.         while (true)  
  32.         {  
  33.             sleep(5000);  // 使主線程延遲5秒  
  34.             flag = !flag;  
  35.             if (flag)  
  36.                 thread.suspend();   
  37.             else 
  38.                 thread.resume();  
  39.         }  
  40.     }  
  41. }  

從表面上看,使用sleep和suspend所產(chǎn)生的效果類似,但sleep方法并不等同于suspend。它們之間最大的一個(gè)區(qū)別是可以在一個(gè)線程中通過suspend方法來掛起另外一個(gè)線程,如上面代碼中在主線程中掛起了thread線程。而sleep只對當(dāng)前正在執(zhí)行的線程起作用。在上面代碼中分別使sleepThread和主線程休眠了2秒和5秒。在使用sleep時(shí)要注意,不能在一個(gè)線程中來休眠另一個(gè)線程。如main方法中使用thread.sleep(2000)方法是無法使thread線程休眠2秒的,而只能使主線程休眠2秒。

在使用sleep方法時(shí)有兩點(diǎn)需要注意:

1. sleep方法有兩個(gè)重載形式,其中一個(gè)重載形式不僅可以設(shè)毫秒,而且還可以設(shè)納秒(1,000,000納秒等于1毫秒)。但大多數(shù)操作系統(tǒng)平臺上的Java虛擬機(jī)都無法精確到納秒,因此,如果對sleep設(shè)置了納秒,Java虛擬機(jī)將取最接近這個(gè)值的毫秒。

2. 在使用sleep方法時(shí)必須使用throws或try{...}catch{...}。因?yàn)閞un方法無法使用throws,所以只能使用try{...}catch{...}。當(dāng)在線程休眠的過程中,使用interrupt方法(這個(gè)方法將在2.3.3中討論)中斷線程時(shí)sleep會拋出一個(gè)InterruptedException異常。sleep方法的定義如下:

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

三、終止線程的三種方法

有三種方法可以使終止線程。

1.  使用退出標(biāo)志,使線程正常退出,也就是當(dāng)run方法完成后線程終止。

2.  使用stop方法強(qiáng)行終止線程(這個(gè)方法不推薦使用,因?yàn)閟top和suspend、resume一樣,也可能發(fā)生不可預(yù)料的結(jié)果)。

3.  使用interrupt方法中斷線程。

1. 使用退出標(biāo)志終止線程

當(dāng)run方法執(zhí)行完后,線程就會退出。但有時(shí)run方法是永遠(yuǎn)不會結(jié)束的。如在服務(wù)端程序中使用線程進(jìn)行監(jiān)聽客戶端請求,或是其他的需要循環(huán)處理的任務(wù)。在這種情況下,一般是將這些任務(wù)放在一個(gè)循環(huán)中,如while循環(huán)。如果想讓循環(huán)永遠(yuǎn)運(yùn)行下去,可以使用while(true){...}來處理。但要想使while循環(huán)在某一特定條件下退出,最直接的方法就是設(shè)一個(gè)boolean類型的標(biāo)志,并通過設(shè)置這個(gè)標(biāo)志為true或false來控制while循環(huán)是否退出。下面給出了一個(gè)利用退出標(biāo)志終止線程的例子。

 
 
 
  1. package chapter2;  
  2.  
  3. public class ThreadFlag extends Thread  
  4. {  
  5.     public volatile boolean exit = false;  
  6.  
  7.     public void run()  
  8.     {  
  9.         while (!exit);  
  10.     }  
  11.     public static void main(String[] args) throws Exception  
  12.     {  
  13.         ThreadFlag thread = new ThreadFlag();  
  14.         thread.start();  
  15.         sleep(5000); // 主線程延遲5秒  
  16.         thread.exit = true;  // 終止線程thread  
  17.         thread.join();  
  18.         System.out.println("線程退出!");  
  19.     }  
  20. }  

在上面代碼中定義了一個(gè)退出標(biāo)志exit,當(dāng)exit為true時(shí),while循環(huán)退出,exit的默認(rèn)值為false。在定義exit時(shí),使用了一個(gè)Java關(guān)鍵字volatile,這個(gè)關(guān)鍵字的目的是使exit同步,也就是說在同一時(shí)刻只能由一個(gè)線程來修改exit的值,

2. 使用stop方法終止線程

使用stop方法可以強(qiáng)行終止正在運(yùn)行或掛起的線程。我們可以使用如下的代碼來終止線程:

thread.stop();
雖然使用上面的代碼可以終止線程,但使用stop方法是很危險(xiǎn)的,就象突然關(guān)閉計(jì)算機(jī)電源,而不是按正常程序關(guān)機(jī)一樣,可能會產(chǎn)生不可預(yù)料的結(jié)果,因此,并不推薦使用stop方法來終止線程。

3. 使用interrupt方法終止線程

使用interrupt方法來終端線程可分為兩種情況:

(1)線程處于阻塞狀態(tài),如使用了sleep方法。

(2)使用while(!isInterrupted()){...}來判斷線程是否被中斷。

在第一種情況下使用interrupt方法,sleep方法將拋出一個(gè)InterruptedException例外,而在第二種情況下線程將直接退出。下面的代碼演示了在第一種情況下使用interrupt方法。

 
 
 
  1. package chapter2;  
  2.  
  3. public class ThreadInterrupt extends Thread  
  4. {  
  5.     public void run()  
  6.     {  
  7.         try 
  8.         {  
  9.             sleep(50000);  // 延遲50秒  
  10.         }  
  11.         catch (InterruptedException e)  
  12.         {  
  13.             System.out.println(e.getMessage());  
  14.         }  
  15.     }  
  16.     public static void main(String[] args) throws Exception  
  17.     {  
  18.         Thread thread = new ThreadInterrupt();  
  19.         thread.start();  
  20.         System.out.println("在50秒之內(nèi)按任意鍵中斷線程!");  
  21.         System.in.read();  
  22.         thread.interrupt();  
  23.         thread.join();  
  24.         System.out.println("線程已經(jīng)退出!");  
  25.     }  
  26. }  

上面代碼的運(yùn)行結(jié)果如下:

在50秒之內(nèi)按任意鍵中斷線程!

sleep interrupted
線程已經(jīng)退出!

在調(diào)用interrupt方法后, sleep方法拋出異常,然后輸出錯(cuò)誤信息:sleep interrupted。

注意:在Thread類中有兩個(gè)方法可以判斷線程是否通過interrupt方法被終止。一個(gè)是靜態(tài)的方法interrupted(),一個(gè)是非靜態(tài)的方法isInterrupted(),這兩個(gè)方法的區(qū)別是interrupted用來判斷當(dāng)前線是否被中斷,而isInterrupted可以用來判斷其他線程是否被中斷。因此,while (!isInterrupted())也可以換成while (!Thread.interrupted())。

以上就是線程的生命周期。要進(jìn)一步學(xué)習(xí)Java多線程,務(wù)必要對Java線程生命周期有著足夠的認(rèn)識。

【編輯推薦】

  1. 初學(xué)Java多線程:使用Runnable接口創(chuàng)建線程
  2. 初學(xué)Java多線程:用Thread類創(chuàng)建線程
  3. 初學(xué)Java多線程:線程簡介
  4. Java多線程編程的常見陷阱
  5. Java多線程的相關(guān)機(jī)制

新聞名稱:初學(xué)Java多線程:線程的生命周期
分享鏈接:http://www.dlmjj.cn/article/cdejggo.html