Java(37)線程基礎及多線程的實現


作者:季沐測試筆記
原文地址https://www.cnblogs.com/testero/p/15130935.html
博客主頁https://www.cnblogs.com/testero

1 進程和線程

1.1 進程:正在運行的程序

是系統進行資源分配和調用的獨立單位
每一個進程都有它自己的內存空間和系統資源

1.2 線程是進程中的單個順序控制流,是一條執行路徑

單線程 即一個控制流,多線程即多個控制流

2 多線程的實現

2.1 繼承Thread實現:

  • 方法介紹

    方法名 說明
    void run() 在線程開啟后,此方法將被調用執行
    void start() 使此線程開始執行,Java虛擬機會調用run方法()
  • 實現步驟

    • 定義一個類繼承Thread類
    • 在類中重寫run()方法
    • 創建類的對象
    • 啟動線程
  • 代碼示例

public class ThreadDemo extends Thread{
    @Override
    public void run() {
        for (int i = 1;i < 20;i++){
            System.out.println(getName()+":"+i);
        }
    }

    public static void main(String[] args) {
        ThreadDemo threadDemo1 = new ThreadDemo();
        ThreadDemo threadDemo2 = new ThreadDemo();

        threadDemo1.setName("線程1");
        threadDemo2.setName("線程2");
        System.out.println(threadDemo1.getPriority());
        System.out.println(threadDemo2.getPriority());
        threadDemo2.setPriority(6);
        threadDemo1.start();
        threadDemo2.start();
        System.out.println(Thread.currentThread().getName());
    }

}

2.1.1 注意:

  • run方法封裝線程執行的代碼,直接調用,相當於普通的方法
  • start啟動線程,然后由JVM調用此線程的run方法

2.1.2 獲取和設置線程名稱

  • 方法介紹

    方法名 說明
    void setName(String name) 將此線程的名稱更改為等於參數name
    String getName() 返回此線程的名稱
    Thread currentThread() 返回對當前正在執行的線程對象的引用

2.1.3 線程調度模型

  • 模型分類
    1、分時調度 所有線程輪流使用CPU的使用權,平均分配每個線程占用CPU的時間片
    2、搶占調度 優先讓優先級高的線程使用CPU,如果線程的優先級相同會隨機選擇一個

  • Thread()類中獲取和設置優先級的方法

    • 獲取優先級public final int getPriority()
    • 設置優先級public final void setPriority(int newPriority)
    • Thread.MIN_PRIORITY 值為1
    • Thread.MAX_PRIORITY 值為10
    • ThreadDemo.NORM_PRIORITY 值為 5
    • 線程優先級高僅僅表示獲取CPU時間片的幾率高,並不是每次都會優先執行

2.1.4 線程的生命周期

線程一共有五種狀態,線程在各種狀態之間轉換。

2.2 實現Runnable:

  • Thread構造方法

    方法名 說明
    Thread(Runnable target) 分配一個新的Thread對象
    Thread(Runnable target, String name) 分配一個新的Thread對象
  • 實現步驟

    • 定義一個類MyRunnable實現Runnable接口
    • 在MyRunnable類中重寫run()方法
    • 創建MyRunnable類的對象
    • 創建Thread類的對象,把MyRunnable對象作為構造方法的參數
    • 啟動線程
  • 代碼示例

public class RunnableDemo implements Runnable {
    @Override
    public void run() {
        for (int i = 1;i < 100;i++){
            System.out.println(i);
        }
    }

    public static void main(String[] args) {
        RunnableDemo runnableDemo = new RunnableDemo();
        Thread thread1 = new Thread(runnableDemo,"線程1");
        Thread thread2 = new Thread(runnableDemo,"線程2");
        thread1.start();
        thread2.start();

    }
}

與Thread相比,實現Runnable的好處:

  • 避免了Java單繼承的局限性
  • 適合多個相同程序的代碼處理同一個資源的情況,把線程和程序的代碼、數據有效分離,較好的體現了面向對象的思維

3、實現 Callable接口(Callable接口有返回值 Runnable接口無返回值),使用ExecutorService、Callable、Future實現有返回結果的多線程

  • 示例代碼
public class CallableDemo implements Callable {
    //1)重寫抽象方法call方法
    @Override
    public Integer call() throws Exception {
        int result = new Random().nextInt(100);
        System.out.println("執行子線程完成某次計算,結果為"+result);
        return result;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //2)創建Callable接口實現類對象
        CallableDemo callableDemo = new CallableDemo();
        //FutureTask實現了RunnableFuture接口,RunnableFuture繼承了Runnable接口,FutureTask接口就是Runnable接口的實現類
        FutureTask<Integer> task = new FutureTask<>(callableDemo);
        Thread thread1 = new Thread(task); //線程池:省去了創建線程、釋放線程的時間
        //3)開啟新的線程
        thread1.start();
        System.out.println("result="+task.get());
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM