JAVA中如何創建線程?創建線程的兩種方式

目錄

 

一.Java中關於應用程序和進程相關的概念

二.Java具有的五種狀態

三.Java中如何創建線程?創建線程的四種方式的區別

一.Java中關於應用程序和進程相關的概念

在Java中,一個應用程序對應着一個JVM實例(也有地方稱爲JVM進程),一般來說名字默認爲java.exe或者javaw.exe(windows下可以通過任務管理器查看)。Java採用的是單線程編程模型,即在我們自己的程序中如果沒有主動創建線程的話,只會創建一個線程,通常稱爲主線程。但是要注意,雖然只有一個線程來執行任務,不代表JVM中只有一個線程,JVM實例在創建的時候,同時會創建很多其他的線程(比如垃圾收集器線程)

由於Java採用的是單線程編程模型,因此在進行UI編程時要注意將耗時的操作放在子線程中進行,以避免阻塞主線程(在UI編程時,主線程即UI線程,用來處理用戶的交互事件)。

二.Java具有的五種狀態

新建狀態(New):當線程對象對創建後,即進入了新建狀態,如:Thread t = new MyThread();


就緒狀態(Runnable):當調用線程對象的start()方法(t.start();),線程即進入就緒狀態。處於就緒狀態的線程,只是說明此線程已經做好了準備,隨時等待CPU調度執行,並不是說執行了t.start()此線程立即就會執行;


運行狀態(Running):當CPU開始調度處於就緒狀態的線程時,此時線程才得以真正執行,即進入到運行狀態。注:就 緒狀態是進入到運行狀態的唯一入口,也就是說,線程要想進入運行狀態執行,首先必須處於就緒狀態中;


阻塞狀態(Blocked):處於運行狀態中的線程由於某種原因,暫時放棄對CPU的使用權,停止執行,此時進入阻塞狀態,直到其進入到就緒狀態,才 有機會再次被CPU調用以進入到運行狀態。根據阻塞產生的原因不同,阻塞狀態又可以分爲三種:


1.等待阻塞:運行狀態中的線程執行wait()方法,使本線程進入到等待阻塞狀態;


2.同步阻塞 -- 線程在獲取synchronized同步鎖失敗(因爲鎖被其它線程所佔用),它會進入同步阻塞狀態;

死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命週期。


三.Java中如何創建線程?創建線程的四種方式的區別

1)繼承Thread類創建線程

2)實現Runnable接口創建線程


1.繼承Thread類,重寫該類的run()方法

(1)繼承Thread類並重寫run方法

(2)創建線程對象並調用start方法

private String name;

    public Talk(String name){
   this.name = name;
    }
    @Override
    public void run() {
        for(int i=1;i<=10;i++){
            System.out.printf("to %s:%d\n",name,i);
            try {
                Thread.sleep((int)(Math.random()*500));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.printf("to %s:bye bye!\n",name);
    }
}




  public static void main(String[] args) {
        Talk zhang = new Talk("zhang");
        Talk li = new Talk("li");

        zhang.start();
        li.start();
    }
}

 2.實現Runnable接口,並重寫該接口的run()方法,該run()方法同樣是線程執行體,創建Runnable實現類的實例,並以此實例作爲Thread類的target來創建Thread對象,該Thread對象纔是真正的線程對象。

(1)實現Runnable接口繼承Thread類並實現run方法

(2)創建實現了Runnable接口類的實例

public class Talk implements Runnable {
    private  Thread t;
        private String name;

    Talk( String name) {
        name = name;
        System.out.println("Creating " +  name );
    }

    @Override
        public void run() {
            for(int i=1;i<=10;i++){
                System.out.printf("to %s:%d\n",name,i);
                try {
                    Thread.sleep((int)(Math.random()*500));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.printf("to %s:bye bye!\n",name);
        }
    public void start () {
        System.out.println("Starting " +  name );
        if (t == null) {
            t = new Thread (this, name);
            t.start ();
        }
    }

}


public static void main(String[] args) {
    Runnable r1 = new Talk("li") ;
    Runnable r2 = new Talk("zhang") ;

    Thread run1 = new Thread(r1);
    Thread run2 = new Thread(r2);
    run1.start();
    run2.start();
}

 

Runnable接口同樣能達到實現多線程的目的Thread類是在java.lang包中定義的。一個類只要繼承了Thread類同時覆寫了本類中的

run()方法就可以實現多線程操作了,但是一個類只能繼承一個父類,這是此方法的侷限。

在使用Runnable定義的子類中沒有start()方法,只有Thread類中才有。

 

(1)通過傳遞實例創建線程對象並調用start方法

接口方式的優勢:

(2)避免單繼承的侷限性;

適合擁有相同代碼的線程處理同一資源的情況。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章