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

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

 更新時(shí)間:2014年01月23日 14:11:00   投稿:zxhpj  
線程要經(jīng)歷開(kāi)始(等待)、運(yùn)行、掛起和停止四種不同的狀態(tài)。這四種狀態(tài)都可以通過(guò)Thread類中的方法進(jìn)行控制。下面給出了Thread類中和這四種狀態(tài)相關(guān)的方法

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

// 開(kāi)始線程
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)時(shí),可以通過(guò)Thread類的方法來(lái)設(shè)置線程不各種屬性,如線程的優(yōu)先級(jí)(setPriority)、線程名(setName)和線程的類型(setDaemon)等。
當(dāng)調(diào)用start方法后,線程開(kāi)始執(zhí)行run方法中的代碼。線程進(jìn)入運(yùn)行狀態(tài)??梢酝ㄟ^(guò)Thread類的isAlive方法來(lái)判斷線程是否處于運(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返回值。

復(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方法,這個(gè)方法的主要功能是保證線程的run方法完成后程序才繼續(xù)運(yùn)行,這個(gè)方法將在后面的文章中介紹
上面代碼的運(yùn)行結(jié)果:
isAlive: false
isAlive: true
thread1已經(jīng)結(jié)束!
isAlive: false

二、掛起和喚醒線程

一但線程開(kāi)始執(zhí)行run方法,就會(huì)一直到這個(gè)run方法執(zhí)行完成這個(gè)線程才退出。但在線程執(zhí)行的過(guò)程中,可以通過(guò)兩個(gè)方法使線程暫時(shí)停止執(zhí)行。這兩個(gè)方法是suspend和sleep。在使用suspend掛起線程后,可以通過(guò)resume方法喚醒線程。而使用sleep使線程休眠后,只能在設(shè)定的時(shí)間后使線程處于就緒狀態(tài)(在線程休眠結(jié)束后,線程不一定會(huì)馬上執(zhí)行,只是進(jìn)入了就緒狀態(tài),等待著系統(tǒng)進(jìn)行調(diào)度)。
雖然suspend和resume可以很方便地使線程掛起和喚醒,但由于使用這兩個(gè)方法可能會(huì)造成一些不可預(yù)料的事情發(fā)生,因此,這兩個(gè)方法被標(biāo)識(shí)為deprecated標(biāo)記,這表明在以后的jdk版本中這兩個(gè)方法可能被刪除,所以盡量不要使用這兩個(gè)方法來(lái)操作線程。下面的代碼演示了sleep、suspend和resume三個(gè)方法的使用。

復(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(); // 開(kāi)始運(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。它們之間最大的一個(gè)區(qū)別是可以在一個(gè)線程中通過(guò)suspend方法來(lái)掛起另外一個(gè)線程,如上面代碼中在主線程中掛起了thread線程。而sleep只對(duì)當(dāng)前正在執(zhí)行的線程起作用。在上面代碼中分別使sleepThread和主線程休眠了2秒和5秒。在使用sleep時(shí)要注意,不能在一個(gè)線程中來(lái)休眠另一個(gè)線程。如main方法中使用thread.sleep(2000)方法是無(wú)法使thread線程休眠2秒的,而只能使主線程休眠2秒。
在使用sleep方法時(shí)有兩點(diǎn)需要注意:
1. sleep方法有兩個(gè)重載形式,其中一個(gè)重載形式不僅可以設(shè)毫秒,而且還可以設(shè)納秒(1,000,000納秒等于1毫秒)。但大多數(shù)操作系統(tǒng)平臺(tái)上的Java虛擬機(jī)都無(wú)法精確到納秒,因此,如果對(duì)sleep設(shè)置了納秒,Java虛擬機(jī)將取最接近這個(gè)值的毫秒。
2. 在使用sleep方法時(shí)必須使用throws或try{...}catch{...}。因?yàn)閞un方法無(wú)法使用throws,所以只能使用try{...}catch{...}。當(dāng)在線程休眠的過(guò)程中,使用interrupt方法(這個(gè)方法將在2.3.3中討論)中斷線程時(shí)sleep會(huì)拋出一個(gè)InterruptedException異常。sleep方法的定義如下:

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

public static void sleep(long millis)  throws InterruptedException
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í)行完后,線程就會(huì)退出。但有時(shí)run方法是永遠(yuǎn)不會(huì)結(jié)束的。如在服務(wù)端程序中使用線程進(jìn)行客戶端請(qǐng)求,或是其他的需要循環(huán)處理的任務(wù)。在這種情況下,一般是將這些任務(wù)放在一個(gè)循環(huán)中,如while循環(huán)。如果想讓循環(huán)永遠(yuǎn)運(yùn)行下去,可以使用while(true){...}來(lái)處理。但要想使while循環(huán)在某一特定條件下退出,最直接的方法就是設(shè)一個(gè)boolean類型的標(biāo)志,并通過(guò)設(shè)置這個(gè)標(biāo)志為true或false來(lái)控制while循環(huán)是否退出。下面給出了一個(gè)利用退出標(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("線程退出!");
}
}

在上面代碼中定義了一個(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同步,也就是說(shuō)在同一時(shí)刻只能由一個(gè)線程來(lái)修改exit的值,

2. 使用stop方法終止線程

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

3. 使用interrupt方法終止線程
使用interrupt方法來(lái)終端線程可分為兩種情況:
(1)線程處于阻塞狀態(tài),如使用了sleep方法。
(2)使用while(!isInterrupted()){...}來(lái)判斷線程是否被中斷。
在第一種情況下使用interrupt方法,sleep方法將拋出一個(gè)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方法拋出異常,然后輸出錯(cuò)誤信息:sleep interrupted。
注意:在Thread類中有兩個(gè)方法可以判斷線程是否通過(guò)interrupt方法被終止。一個(gè)是靜態(tài)的方法interrupted(),一個(gè)是非靜態(tài)的方法isInterrupted(),這兩個(gè)方法的區(qū)別是interrupted用來(lái)判斷當(dāng)前線是否被中斷,而isInterrupted可以用來(lái)判斷其他線程是否被中斷。因此,while (!isInterrupted())也可以換成while (!Thread.interrupted())。

相關(guān)文章

  • java實(shí)現(xiàn)在復(fù)制文件時(shí)使用進(jìn)度條(java實(shí)現(xiàn)進(jìn)度條)

    java實(shí)現(xiàn)在復(fù)制文件時(shí)使用進(jìn)度條(java實(shí)現(xiàn)進(jìn)度條)

    在對(duì)大文件操作時(shí),可能會(huì)需要些時(shí)間,此時(shí)為用戶提供進(jìn)度條提示是非常常見(jiàn)的一項(xiàng)功能,這樣用戶就可以了解操作文件需要的時(shí)間信息。本實(shí)例為大家介紹了在復(fù)制大的文件時(shí)使用的進(jìn)度條提示,需要注意的是,只有在讀取文件超過(guò)2秒時(shí),才會(huì)顯示進(jìn)度條
    2014-03-03
  • Java?Git?Commit?Message使用規(guī)范

    Java?Git?Commit?Message使用規(guī)范

    這篇文章主要介紹了Java?Git?Commit?Message使用規(guī)范,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下,希望對(duì)你的學(xué)習(xí)有所幫助
    2022-08-08
  • java之Thread不捕獲異常默認(rèn)處理邏輯

    java之Thread不捕獲異常默認(rèn)處理邏輯

    這篇文章主要介紹了java之Thread不捕獲異常默認(rèn)處理邏輯,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • spring boot集成shiro詳細(xì)教程(小結(jié))

    spring boot集成shiro詳細(xì)教程(小結(jié))

    這篇文章主要介紹了spring boot 集成shiro詳細(xì)教程,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • MyBatis Mapper接受參數(shù)的四種方式代碼解析

    MyBatis Mapper接受參數(shù)的四種方式代碼解析

    這篇文章主要介紹了MyBatis Mapper接受參數(shù)的四種方式代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Spring Shell應(yīng)用程序開(kāi)發(fā)流程解析

    Spring Shell應(yīng)用程序開(kāi)發(fā)流程解析

    這篇文章主要介紹了Spring Shell應(yīng)用程序開(kāi)發(fā)流程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • SpringBoot過(guò)濾器與攔截器深入分析實(shí)現(xiàn)方法

    SpringBoot過(guò)濾器與攔截器深入分析實(shí)現(xiàn)方法

    大家應(yīng)該都曉得實(shí)現(xiàn)過(guò)濾器需要實(shí)現(xiàn) javax.servlet.Filter 接口,而攔截器會(huì)在處理指定請(qǐng)求之前和之后進(jìn)行相關(guān)操作,配置攔截器需要兩步,本文通過(guò)實(shí)例代碼給大家介紹SpringBoot 過(guò)濾器和攔截器的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2022-11-11
  • mybatis 返回Map類型key改為小寫的操作

    mybatis 返回Map類型key改為小寫的操作

    這篇文章主要介紹了mybatis 返回Map類型key改為小寫的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • springboot+jwt+微信小程序授權(quán)登錄獲取token的方法實(shí)例

    springboot+jwt+微信小程序授權(quán)登錄獲取token的方法實(shí)例

    本文主要介紹了springboot+jwt+微信小程序授權(quán)登錄獲取token的方法實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Mybatis源碼分析之存儲(chǔ)過(guò)程調(diào)用和運(yùn)行流程

    Mybatis源碼分析之存儲(chǔ)過(guò)程調(diào)用和運(yùn)行流程

    這一篇我們學(xué)習(xí)一下Mybatis調(diào)用存儲(chǔ)過(guò)程的使用和運(yùn)行流程,首先我們創(chuàng)建一個(gè)簡(jiǎn)單的存儲(chǔ)過(guò)程,具體創(chuàng)建過(guò)程大家可以通過(guò)本文學(xué)習(xí)下
    2016-11-11

最新評(píng)論