1. 程式人生 > >Java多執行緒一些基礎知識

Java多執行緒一些基礎知識

最近複習了一些多執行緒方面的基礎知識,做一下總結,多以自己的理解來文字敘述,如果有漏點或者理解錯的地方,歡迎各位大佬多多指出;

ps:執行緒分為使用者執行緒和守護執行緒,當程式中的所有的使用者執行緒都執行完了之後,JVM就退出執行了,下面所講的都是使用者執行緒為例,我們一般建立一個新執行緒物件,預設都是使用者執行緒,當然,我們可以手動呼叫setDeamon(true);置為守護執行緒;這個涉及到執行緒優先順序的問題了,後面會詳細說明;

執行緒的生命週期:

1. 新建狀態(New)  : 執行緒物件被建立後,就進入了新建狀態。例如,Thread thread = new Thread()。2. 就緒狀態(Runnable)

: 也被稱為“可執行狀態”。執行緒物件被建立後,其它執行緒呼叫了該物件的start()方法,從而來啟動該執行緒。例如,thread.start()。處於就緒狀態的執行緒,隨時可能被CPU排程執行。3. 執行狀態(Running) : 執行緒獲取CPU許可權進行執行。需要注意的是,執行緒只能從就緒狀態進入到執行狀態。4. 阻塞狀態(Blocked)  : 阻塞狀態是執行緒因為某種原因放棄CPU使用權,暫時停止執行。直到執行緒進入就緒狀態,才有機會轉到執行狀態。阻塞的情況分三種:    (01) 等待阻塞 -- 通過呼叫執行緒的wait()方法,讓執行緒等待某工作的完成。    (02) 同步阻塞 -- 執行緒在獲取synchronized同步鎖失敗(因為鎖被其它執行緒所佔用),它會進入同步阻塞狀態。    (03) 其他阻塞 -- 通過呼叫執行緒的sleep()或join()或發出了I/O請求時,執行緒會進入到阻塞狀態。當sleep()狀態超時、join()等待執行緒終止或者超時、或者I/O處理完畢時,執行緒重新轉入就緒狀態。5. 死亡狀態(Dead)
    : 執行緒執行完了或者因異常退出了run()方法,該執行緒結束生命週期。

實現多執行緒的方式有兩種:繼承Thread類和實現Runnable介面,繼承和實現各有各的特點,怎麼選擇可根據業務來決定,一般為了更好的擴充套件都是選擇實現Runnable介面;

// 實現Runnable的方式
class MyThread implements Runnable{  
    private int ticket=10;  
    public void run(){
        for(int i=0;i<20;i++){ 
            if(this.ticket>0){
                System.out.println(Thread.currentThread().getName()
+" 賣票:ticket"+this.ticket--); } } } }; public class RunnableTest { public static void main(String[] args) { MyThread mt=new MyThread(); // 啟動3個執行緒t1,t2,t3(它們共用一個Runnable物件),這3個執行緒一共賣10張票! Thread t1=new Thread(mt); Thread t2=new Thread(mt); Thread t3=new Thread(mt); t1.start(); t2.start(); t3.start(); } }
// 繼承Thread類的方式
class MyThread extends Thread{  
    private int ticket=10;  
    public void run(){
        for(int i=0;i<20;i++){ 
            if(this.ticket>0){
                System.out.println(this.getName()+" 賣票:ticket"+this.ticket--);
            }
        }
    } 
};

public class ThreadTest {  
    public static void main(String[] args) {  
        // 啟動3個執行緒t1,t2,t3;每個執行緒各賣10張票!
        MyThread t1=new MyThread();
        MyThread t2=new MyThread();
        MyThread t3=new MyThread();
        t1.start();
        t2.start();
        t3.start();
    }  
}

其中如果是選擇繼承Thread類的方式的話,因為每new一個執行緒物件,都會產生一個獨立的物件,所以每個物件都會執行10次迴圈;

實現runnable介面,三個執行緒共享一個MyThread物件,所以3個執行緒一共執行10次迴圈;