(十四)java併發程式設計--執行緒的阻塞
阿新 • • 發佈:2018-12-24
java中我們可以使用執行緒類的三種方式來阻止執行緒的執行。
執行緒的狀態圖如下(圖片來自網路):
1、yield()
yield英文的意思是屈服,如同其意,當前執行緒屈服,暫停,讓同等優先順序的執行緒執行。
yield()方法可以暫停當前執行的執行緒,以便為相同優先順序的其他等待執行緒提供機會, 如果沒有等待執行緒, 或者等待執行緒的優先順序較低, 那麼相同的執行緒將會執行。當獲得執行機會,產生的執行緒,由執行緒的排程程式決定的。如下程式碼所示:
package thread_create;
/**
* Created by fang on 2017/12/3.
* 暫停自己,讓出cpu排程.yield
*/
public class ThreadYieldDemo extends Thread{
//yield 暫停執行緒,是一個靜態方法.
public static void main(String[] args) throws InterruptedException {
ThreadYieldDemo threadYieldDemo = new ThreadYieldDemo();
Thread thread = new Thread(threadYieldDemo);//xinzheng
thread.start();//就緒狀態.
//cpu排程進入執行.
for(int i=0;i<100;i++){
if(i%20==0){
//暫停本執行緒.
//寫在誰的執行緒裡面就暫停誰.;
Thread.yield();//是一個靜態方法.寫在main中暫停main()
}
System.out.println("main....." + i);
}
}
public void run(){
for(int i=0;i<100;i++){
System.out.println("yield...." +i);
}
}
}
2、join()
任何執行的程式線上程t1上呼叫t2.join()方法,則t1將進入等待狀態,直到t2執行完成t1則繼續執行。
package thread_create;
/**
* Created by fang on 2017/12/3.
*合併執行緒,join
*/
public class ThreadJoinDemo extends Thread {
public static void main(String[] args) throws InterruptedException {
ThreadJoinDemo threadJoinDemo = new ThreadJoinDemo();
Thread thread = new Thread(threadJoinDemo);//xinzheng
thread.start();//就緒狀態.
//cpu排程進入執行.
for(int i=0;i<100;i++){
if(i==50){
thread.join();//前50是join和main執行順序不定,當i==50加上join,則thread先執行完,main再執行.
//main阻塞
}
System.out.println("main....." + i);
}
}
public void run(){
for(int i=0;i<100;i++){
System.out.println("join...." +i);
}
}
}
我們這裡threadJoinDemo是t2, 所以會在i=50的時候會先執行threadJoinDemo, 最後在執行main主執行緒。
3、sleep()
根據我們的要求,可以讓執行緒在指定的時間段內處於睡眠狀態。
package thread_create;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by fang on 2017/12/3.
* sleep demo,暫停當前執行緒,並不會釋放鎖.
* 倒數10個數,1s列印一個.
*/
public class ThreadSleepDemo {
public static void main(String[] args) throws InterruptedException {
//倒數10個數,列印.
int num=10;
while (true){
System.out.println(num--);
Thread.sleep(1000);//暫停.
if(num<=0){
break;
}
}
}
}
sleep()不會釋放資源,直到到了指定時間。
4、wait()
wait()方法一般和notify()、notifyAll()方法使用,這三個方法用於協調多執行緒對共享資料的存取,所以必須在synchronized塊內使用,
也就是說,wait()、notify、notifyAll()的任務在呼叫這些方法前必須擁有物件的鎖。他們是Object的方法,並不是Thread類的方法。
為什麼wait()、notify()、notifyAll()在Object的方法中,卻沒有在Thread中類方法中?
因為都是鎖級別的操作,鎖屬於物件,所以把他們定義到Object中,任何一個物件都可能獲得一把鎖。
物件的wait()方法就不再這裡列舉程式碼了,下篇主要說一下執行緒的死鎖,下篇補充上程式碼示例。
總結:
應該有全域性觀吧,怎麼的方式效率最高,怎樣的方式讓自己的大腦印象更深刻?