首頁 > 軟體

Java並行程式設計之執行緒建立介紹

2022-04-18 16:00:27

1.執行緒與程序

程序是程式碼在資料集合上的一次執行活動,是系統進行資源分配和排程的基本單位,執行緒則是一個實體,一個程序中至少有一個執行緒,是CPU排程和分配的基本單位,程序中的多個執行緒共用程序的資源。

程序的三個特徵:

  • 動態性 : 程序是執行中的程式,要動態的佔用記憶體,CPU和網路等資源。
  • 獨立性 : 程序與程序之間是相互獨立的,彼此有自己的獨立記憶體區域。
  • 並行性 : 假如CPU是單核,同一個時刻其實記憶體中只有一個程序在被執行。CPU會分時輪詢切換依次為每個程序服務,因為切換的速度非常快,給我們的感覺這些程序在同時執行,這就是並行性。

2.執行緒的建立與執行

我們在程序中建立執行緒的方式有三種:

  • 方式一:繼承Thread類的方式
  • 1.定義一個執行緒類繼承Thread類。
  • 2.重寫run()方法
  • 3.建立一個新的執行緒物件。
  • 4.呼叫執行緒物件的start()方法啟動執行緒。
public class ThreadDemo {
    // 啟動後的ThreadDemo當成一個程序。
    // main方法是由主執行緒執行的,理解成main方法就是一個主執行緒
    public static void main(String[] args) {
        // 3.建立一個執行緒物件
        Thread t = new MyThread();
        // 4.呼叫執行緒物件的start()方法啟動執行緒,最終還是執行run()方法!
        t.start();

        for(int i = 0 ; i < 100 ; i++ ){
            System.out.println("main執行緒輸出:"+i);
        }
    }
}

// 1.定義一個執行緒類繼承Thread類。
class MyThread extends Thread{
    // 2.重寫run()方法
    @Override
    public void run() {
        // 執行緒的執行方法。
        for(int i = 0 ; i < 100 ; i++ ){
            System.out.println("子執行緒輸出:"+i);
        }
    }
}

優點:編碼簡單,在run()方法內獲取當前執行緒直接使用this就可以了,無需使用Thread.currentThread()方法。 缺點:執行緒類已經繼承了Thread類無法繼承其他類了,功能不能通過繼承拓(單繼承的侷限性)。另外任務與程式碼沒有分離,當多個執行緒執行一樣的任務時需要多份任務程式碼。

小結:

  • 執行緒類是繼承了Thread的類。
  • 啟動執行緒必須呼叫start()方法。
  • 多執行緒是並行搶佔CPU執行,所以在執行的過程中會出現並行隨機性

方式二:實現Runnable介面的方式。

  • 1.建立一個執行緒任務類實現Runnable介面。
  • 2.重寫run()方法
  • 3.建立一個執行緒任務物件。
  • 4.把執行緒任務物件包裝成執行緒物件
  • 5.呼叫執行緒物件的start()方法啟動執行緒。
public class ThreadDemo {
    public static void main(String[] args) {
        // 3.建立一個執行緒任務物件(注意:執行緒任務物件不是執行緒物件,只是執行執行緒的任務的)
        Runnable target = new MyRunnable();
        // 4.把執行緒任務物件包裝成執行緒物件.且可以指定執行緒名稱
        // Thread t = new Thread(target);
        Thread t = new Thread(target,"1號執行緒");
        // 5.呼叫執行緒物件的start()方法啟動執行緒
        t.start();

        Thread t2 = new Thread(target);
        // 呼叫執行緒物件的start()方法啟動執行緒
        t2.start();

        for(int i = 0 ; i < 10 ; i++ ){
            System.out.println(Thread.currentThread().getName()+"==>"+i);
        }
    }
}

// 1.建立一個執行緒任務類實現Runnable介面。
class MyRunnable implements Runnable{
    // 2.重寫run()方法
    @Override
    public void run() {
        for(int i = 0 ; i < 10 ; i++ ){
            System.out.println(Thread.currentThread().getName()+"==>"+i);
        }
    }
}

優點:

執行緒任務類只是實現了Runnable介面,可以繼續繼承其他類,而且可以繼續實現其他介面(避免了單繼承的侷限性)。 同一個執行緒任務物件可以被包裝成多個執行緒物件,適合多個多個執行緒去共用同一個資源。實現解耦操作,執行緒任務程式碼可以被多個執行緒共用,執行緒任務程式碼和執行緒獨立。

方法三:實現Callable介面

  • 1.定義一個執行緒任務類實現Callable介面 , 申明執行緒執行的結果型別。
  • 2.重寫執行緒任務類的call方法,這個方法可以直接返回執行的結果。
  • 3.建立一個Callable的執行緒任務物件。
  • 4.把Callable的執行緒任務物件包裝成一個FutureTask物件。
  • 5.把FutureTask物件包裝成執行緒物件。
  • 6.呼叫執行緒的start()方法啟動執行緒 。
public class ThreadDemo {
    public static void main(String[] args) {
        // 3.建立一個Callable的執行緒任務物件
        Callable call = new MyCallable();
        // 4.把Callable任務物件包裝成一個未來任務物件
        //      -- public FutureTask(Callable<V> callable)
        // 未來任務物件是啥,有啥用?
        //      -- 未來任務物件其實就是一個Runnable物件:這樣就可以被包裝成執行緒物件!
        //      -- 未來任務物件可以線上程執行完畢之後去得到執行緒執行的結果。
        FutureTask<String> task = new FutureTask<>(call);
        // 5.把未來任務物件包裝成執行緒物件
        Thread t = new Thread(task);
        // 6.啟動執行緒物件
        t.start();

        for(int i = 1 ; i <= 10 ; i++ ){
            System.out.println(Thread.currentThread().getName()+" => " + i);
        }

        // 在最後去獲取執行緒執行的結果,如果執行緒沒有結果,讓出CPU等執行緒執行完再來取結果
        try {
            String rs = task.get(); // 獲取call方法返回的結果(正常/異常結果)
            System.out.println(rs);
        }  catch (Exception e) {
            e.printStackTrace();
        }

    }
}

// 1.建立一個執行緒任務類實現Callable介面,申明執行緒返回的結果型別
class MyCallable implements Callable<String>{
    // 2.重寫執行緒任務類的call方法!
    @Override
    public String call() throws Exception {
        // 需求:計算1-10的和返回
        int sum = 0 ;
        for(int i = 1 ; i <= 10 ; i++ ){
            System.out.println(Thread.currentThread().getName()+" => " + i);
            sum+=i;
        }
        return Thread.currentThread().getName()+"執行的結果是:"+sum;
    }
}

優點: 執行緒任務類只是實現了Callable介面,可以繼續繼承其他類,而且可以繼續實現其他介面(避免了單繼承的侷限性)。 同一個執行緒任務物件可以被包裝成多個執行緒物件,適合多個多個執行緒去共用同一個資源。實現解耦操作,執行緒任務程式碼可以被多個執行緒共用,執行緒任務程式碼和執行緒獨立。最關鍵的是能直接得到執行緒執行的結果。

到此這篇關於Java並行程式設計之執行緒建立的文章就介紹到這了,更多相關Java 執行緒建立內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com