欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java線程之線程的生命周期的使用

 更新時間:2013年05月02日 16:18:25   作者:  
本篇文章介紹了,java線程之線程的生命周期的使用。需要的朋友參考下

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

復(fù)制代碼 代碼如下:

// 開始線程
     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( );

     // 得到線程狀態(tài)
     public boolean isAlive( );
     public boolean isInterrupted( );
     public static boolean interrupted( );

     // join方法
     public void join( ) throws InterruptedException;

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

    線程在建立后并不馬上執(zhí)行run方法中的代碼,而是處于等待狀態(tài)。線程處于等待狀態(tài)時,可以通過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)時,isAlive返回true,當(dāng)isAlive返回false時,可能線程處于等待狀態(tài),也可能處于停止?fàn)顟B(tài)。下面的代碼演示了線程的創(chuàng)建、運(yùn)行和停止三個狀態(tài)之間的切換,并輸出了相應(yīng)的isAlive返回值。

復(fù)制代碼 代碼如下:

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結(jié)束后再繼續(xù)執(zhí)行
         System.out.println("thread1已經(jīng)結(jié)束!");
         System.out.println("isAlive: " + thread1.isAlive());
     }
 }

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

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

復(fù)制代碼 代碼如下:

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

二、掛起和喚醒線程

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

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

復(fù)制代碼 代碼如下:

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

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

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

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

復(fù)制代碼 代碼如下:

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)行終止線程(這個方法不推薦使用,因為stop和suspend、resume一樣,也可能發(fā)生不可預(yù)料的結(jié)果)。

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

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

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

復(fù)制代碼 代碼如下:

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("線程退出!");
     }
 }

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

    2. 使用stop方法終止線程

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

復(fù)制代碼 代碼如下:

1 thread.stop();

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

    3. 使用interrupt方法終止線程

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

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

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

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

復(fù)制代碼 代碼如下:

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秒之內(nèi)按任意鍵中斷線程!");
         System.in.read();
         thread.interrupt();
         thread.join();
         System.out.println("線程已經(jīng)退出!");
     }
 }

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

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

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


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

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

相關(guān)文章

  • java中實現(xiàn)遞歸計算二進(jìn)制表示中1的個數(shù)

    java中實現(xiàn)遞歸計算二進(jìn)制表示中1的個數(shù)

    這是一個很有意思的問題,是在面試中特別容易被問到的問題之一,解決這個問題第一想法肯定是一位一位的去判斷,是1計數(shù)器+1,否則不操作,跳到下一位,十分容易,編程初學(xué)者就可以做得到!
    2015-05-05
  • 分析ZooKeeper分布式鎖的實現(xiàn)

    分析ZooKeeper分布式鎖的實現(xiàn)

    在分布式的情況下,sychornized 和 Lock 已經(jīng)不能滿足我們的要求了,那么就需要使用第三方的鎖了,這里我們就使用 ZooKeeper 來實現(xiàn)一個分布式鎖
    2021-06-06
  • mybatis自定義類型處理器TypehHandler示例詳解

    mybatis自定義類型處理器TypehHandler示例詳解

    我們在寫mapper映射器的配置文件時,不經(jīng)意間已經(jīng)用到類型轉(zhuǎn)換,不過是mybatis幫我們完成的,下面這篇文章主要給大家介紹了關(guān)于mybatis自定義類型處理器TypehHandler的相關(guān)資料,需要的朋友可以參考下
    2018-09-09
  • SpringMvc直接接收json數(shù)據(jù)自動轉(zhuǎn)化為Map的實例

    SpringMvc直接接收json數(shù)據(jù)自動轉(zhuǎn)化為Map的實例

    今天小編就為大家分享一篇SpringMvc直接接收json數(shù)據(jù)自動轉(zhuǎn)化為Map的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • java設(shè)計模式之工廠方法模式

    java設(shè)計模式之工廠方法模式

    這篇文章主要為大家詳細(xì)介紹了java設(shè)計模式之工廠方法模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • 解決springboot中配置過濾器以及可能出現(xiàn)的問題

    解決springboot中配置過濾器以及可能出現(xiàn)的問題

    這篇文章主要介紹了解決springboot中配置過濾器以及可能出現(xiàn)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Java利用Redis實現(xiàn)高并發(fā)計數(shù)器的示例代碼

    Java利用Redis實現(xiàn)高并發(fā)計數(shù)器的示例代碼

    這篇文章主要介紹了Java利用Redis實現(xiàn)高并發(fā)計數(shù)器的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Spring?AOP對嵌套方法不起作用的解決

    Spring?AOP對嵌套方法不起作用的解決

    這篇文章主要介紹了Spring?AOP對嵌套方法不起作用的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 微服務(wù)eureka和nacos案例詳解

    微服務(wù)eureka和nacos案例詳解

    這篇文章主要介紹了微服務(wù)eureka和nacos,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • Java SpringBoot容器注入對象詳解

    Java SpringBoot容器注入對象詳解

    本文通過實例代碼給大家詳解了springboot獲取ioc容器中注入的bean問題,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-09-09

最新評論