線程控制基本方法 方 法 功 能 isAlive() 判斷線程是否還“活”著,即當前run線程是否還未終止。 getPriority() 獲得線程的優先級數值 setPriority() 設置線程的優先級數值 Thread.sleep() 將當前線程睡眠指定毫秒數 join() 調用某線程的該方法,將當前線程與該線程“合并”,即等待該線程結束,再恢復當前線程的運行。 yield() 讓出CPU,當前線程進入就緒隊列等待調度。 wait() 當前線程進入對象的wait pool。 notify()/notifyAll() 喚醒對象的wait pool中的一個/所有等待線程。 run()和start()
這兩個方法應該都比較熟悉,把需要并行處理的代碼放在run()方法中,start()方法啟動線程將自動調用 run()方法,這是由Java的內存機制規定的。并且run()方法必須是public訪問權限,返回值類型為void。 isAlive方法實例:
interrupt/sleep方法: 可以調用Thread的靜態方法: public static void sleep(long millis) throws InterruptedException 使得當前線程休眠(暫時停止執行millis毫秒)。 由于是靜態方法,sleep可以由類名直接調用:Thread.sleep(…)
使當前線程(即調用該方法的線程)暫停執行一段時間,讓其他線程有機會繼續執行,但它并不釋放對象鎖。也就是如果有Synchronized同步塊,其他線程仍然不同訪問共享數據。注意該方法要捕獲異常
比如有兩個線程同時執行(沒有Synchronized),一個線程優先級為MAX_PRIORITY,另一個為MIN_PRIORITY,如果沒有 Sleep()方法,只有高優先級的線程執行完成后,低優先級的線程才能執行;但當高優先級的線程sleep(5000)后,低優先級就有機會執行了。
總之,sleep()可以使低優先級的線程得到執行的機會,當然也可以讓同優先級、高優先級的線程有執行的機會。
停止線程的方法中,stop最強暴,其次便是interrupte,這兩種都是不提倡的,推薦的方法是通過flag標志來終止線程,例如:
join方法: 合并某個線程,,join()方法使調用該方法的線程在此之前執行完畢,也就是等待調用該方法的線程執行完畢后再往下繼續執行。注意該方法也要捕獲異常。
yield方法: 暫時讓出CPU,給其他線程執行的機會,它與sleep()類似,只是不能由用戶指定暫停多長時間,并且yield()方法只能讓同優先級的線程有執行的機會。
setPriority():
關鍵字Synchronized
這個關鍵字用于保護共享數據,當然前提是要分清哪些數據是共享數據。每個對象都有一個鎖標志,當一個線程訪問該對象時,被Synchronized修飾的數據將被“上鎖”,阻止其他線程訪問。當前線程訪問完這部分數據后釋放鎖標志,其他線程就可以訪問了。
注意以下這個例子
結果: 0 0 1 2 3 4 1 5 2 6 3 7 4 8 9 5 6 7 8 9 ;(不同對象) 以上這段程序中的 i 變量并不是共享數據,這個程序中的t1,t2分別是兩個對象(r1,r2)的線程。JAVA是面向對象的程序設計語言,不同的對象的數據是不同的,r1,r2有各自的run()方法,而synchronized使同一個對象的多個線程,在某個時刻只有其中的一個線程可以訪問這個對象的synchronized數據。
當把代碼改成如下:Synchronized關鍵字才會起作用
Runnable r = new ThreadTest();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
synchronized 導致的死鎖問題:
wait()和notify()、notifyAll()
這三個方法用于協調多個線程對共享數據的存取,所以必須在Synchronized語句塊內使用這三個方法。前面說過Synchronized這個關鍵字用于保護共享數據,阻止其他線程對共享數據的存取。但是這樣程序的流程就很不靈活了,如何才能在當前線程還沒退出Synchronized數據塊時讓其他線程也有機會訪問共享數據呢?此時就用這三個方法來靈活控制。
wait()方法使當前線程暫停執行并釋放對象鎖標志,讓其他線程可以進入Synchronized數據塊,當前線程被放入對象等待池中。當調用 notify()方法后,將從對象的等待池中移走一個任意的線程并放到鎖標志等待池中,只有
鎖標志等待池中的線程能夠獲取鎖標志;如果鎖標志等待池中沒有線程,則notify()不起作用。
notifyAll()則從對象等待池中移走所有等待那個對象的線程并放到鎖標志等待池中。
注意 這三個方法都是java.lang.Ojbect的方法!
Powered by: BlogJava Copyright © Gavin.lee