1. 程式人生 > >(十四)java併發程式設計--執行緒的阻塞

(十四)java併發程式設計--執行緒的阻塞

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()方法就不再這裡列舉程式碼了,下篇主要說一下執行緒的死鎖,下篇補充上程式碼示例。

總結:

應該有全域性觀吧,怎麼的方式效率最高,怎樣的方式讓自己的大腦印象更深刻?