Java中停止線程執行的方法,Java線程執行方法
Java中停止線程執行的方法作者:chszs,轉載需註明。部落客頁:http://blog.csdn.net/chszs一、暫停或停止線程的理論
在Java編程中,要暫停或停止當前正在啟動並執行線程,有幾種方法。對於把線程轉入睡眠Sleep狀態,使用Thread.sleep()是最正確的方式。或許有人會問,為什麼不使用等待wait()或通知notify()?要知道,使用等待或通知都不是很好的方式。
線程可以使用等待wait()實現被阻塞,這屬於條件等待的方式,當條件滿足後,又會從阻塞轉為等待狀態。儘管可以在等待wait()條件那裡放一個逾時設定,但等待wait()的設計目的不是這樣的,等待wait()在設計上是用於Java線程間的通訊。
而使用睡眠sleep()方式,可以讓線程從當前開始睡眠指定的時間。注意不要使用睡眠sleep()方式去代替等待wait()或通知notify(),反之亦然。
等待wait()或通知notify()不應該用於暫停線程,還有一個原因,等待wait()或通知notify()需要一個鎖。只能從一個同步的方法或同步的代碼塊去調用它們,擷取鎖和釋放鎖的開銷是比較大的。而且,只是暫停線程的話,無需引入鎖機制。
sleep()與wait()還有一點不同,sleep()會把當前的線程轉入等待狀態,它不會釋放它持有的任何鎖,而wait()使得線程轉入阻塞狀態,會釋放掉自己持有的鎖。
總之,Java多線程編程並不簡單,即使是簡單的任務,如建立線程、停止線程或暫停線程,都需要認真掌握Java API。
二、暫停或停止線程的實戰
下面的例子中,要暫停線程,可以使用Thread.sleep()或TimeUnit.sleep()方法。例子中,有兩個線程,主線程由JVM啟動,它執行main()方法。第二個線程叫T1,它由主線程建立,用於迴圈運行遊戲。我們傳遞的Runnable任務是一個無限迴圈,會一直運行直到我們停止它。注意看,我使用了volatile關鍵字。
主線程首先啟動T1線程,再使用stop()方法停止線程。
在這個例子中,我們有兩種方法停止線程的運行,使用Thread.sleep()方法或者是使用TimeUnit.sleep()方法。TimeUnit類既可以指定秒即TimeUnit.SECONDS,又可以指定毫秒即TimeUnit.MILLISECONDS。總的來說,使用TimeUnit的sleep()方法,使得代碼更為易讀。
import static java.lang.Thread.currentThread;import java.util.concurrent.TimeUnit;public class ThreadPauseDemo{ public static void main(String args[]) throws InterruptedException { Game game = new Game(); Thread t1 = new Thread(game, "T1"); t1.start(); // 現在停止Game線程 System.out.println(currentThread().getName() + " is stopping game thread"); game.stop(); // 查看Game線程停止的狀態 TimeUnit.MILLISECONDS.sleep(200); System.out.println(currentThread().getName() + " is finished now"); }}class Game implements Runnable{ private volatile boolean isStopped = false; public void run(){ while(!isStopped){ System.out.println("Game thread is running......"); System.out.println("Game thread is now going to pause"); try{ Thread.sleep(200); } catch(InterruptedException e){ e.printStackTrace(); } System.out.println("Game thread is now resumed......"); } System.out.println("Game thread is stopped......"); } public void stop(){ isStopped = true; }}
程式輸出如下:
Game thread is running......main is stopping game threadGame thread is now going to pauseGame thread is now resumed......Game thread is stopped......main is finished now
註:
volatile關鍵字:當一個共用變數被volatile修飾時,它會保證修改的值會立即被更新到主存,當有其他線程需要讀取這個值時,它會去主記憶體中讀取新值。volatile關鍵字保證了可見度。普通的共用變數不能保證可見度,因為普通共用變數被修改之後,什麼時候被寫入主存是不確定的,當其他線程去讀取時,此時記憶體中可能還是原來的舊值,因此無法保證可見度。
通過synchronized和Lock也能夠保證可見度,synchronized和Lock能保證同一時刻只有一個線程擷取鎖然後執行同步代碼,並且在釋放鎖之前會將對變數的修改重新整理到主存當中。因此可以保證可見度。
一個共用變數(類的成員變數、類的靜態成員變數)被volatile修飾之後,那麼它就具備了兩層語義:
volatile關鍵字禁止指令重排序有兩層意思:
三、sleep()方法總結
Thread.sleep()方法可以讓線程暫停或停止,它還有一些細節需要注意:
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。