国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - java多線程編程之線程的生命周期

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

2019-11-04 14:02java教程網 JAVA教程

線程要經歷開始(等待)、運行、掛起和停止四種不同的狀態。這四種狀態都可以通過Thread類中的方法進行控制。下面給出了Thread類中和這四種狀態相關的方法

代碼如下:


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

 

一、創建并運行線程

線程在建立后并不馬上執行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

二、掛起和喚醒線程

一但線程開始執行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

 

三、終止線程的三種方法

有三種方法可以使終止線程。
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())。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲视频综合 | 国产一区二区免费 | 国产成人精品一区二区三区 | 国产精品综合视频 | 久久综合区| 一区二区三区国产 | 日韩精品在线一区二区 | 久久久久久久一区 | 国产二区视频 | 欧美一级二级三级 | 91丁香婷婷综合久久欧美 | 激情视频综合网 | 亚洲精品一区二区三区四区高清 | 99免费在线播放99久久免费 | 一本色道久久综合狠狠躁篇的优点 | 国产精品九九久久99视频 | 日韩一区电影 | 中文字幕一区二区三 | 狠狠艹夜夜艹 | 一区二区三区影视 | 亚洲天堂电影 | 亚洲一区中文 | 自拍偷拍专区 | 一区二区不卡视频 | 色婷婷蜜桃 | 亚洲视频精品在线观看 | 伊人激情网 | 日韩中文字幕 | 一区二区视频 | 一呦二呦三呦国产精品 | 久草电影网 | 日本中文字幕在线观看 | 91视频进入 | 亚洲色图综合 | 久久国产综合 | 欧美第一专区 | 亚洲国产高清视频 | 美女网站全黄 | 老司机午夜免费精品视频 | 亚洲第一免费播放区 | 亚洲日本视频 |