Java線程基礎(chǔ)及多線程的實(shí)現(xiàn)

一、進(jìn)程和線程

? ? 1、進(jìn)程:正在運(yùn)行的程序
? ? ? ? 是系統(tǒng)進(jìn)行資源分配和調(diào)用的獨(dú)立單位
? ? ? ? 每一個進(jìn)程都有它自己的內(nèi)存空間和系統(tǒng)資源

? ? 2、線程是進(jìn)程中的單個順序控制流,是一條執(zhí)行路徑
? ? ? ? 單線程 即一個控制流,多線程即多個控制流

二、多線程的實(shí)現(xiàn)

1、繼承Thread實(shí)現(xiàn):

  • 定義一個類繼承Thread類

  • 在類中重寫run()方法

  • 創(chuàng)建類的對象

  • 啟動線程

    代碼示例

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());
    }

}

注意:

  • run方法封裝線程執(zhí)行的代碼,直接調(diào)用,相當(dāng)于普通的方法
  • start啟動線程,然后由JVM調(diào)用此線程的run方法

獲取和設(shè)置線程名稱

利用getName()即可獲取到線程的名稱,未繼承Thread的使用Thread.currentThread().getName()獲取線程名稱
.setName("")可設(shè)置線程名稱

線程調(diào)度模型

模型分類

? ? 1、分時調(diào)度 所有線程輪流使用CPU的使用權(quán),平均分配每個線程占用CPU的時間片
? ? 2、搶占調(diào)度 優(yōu)先讓優(yōu)先級高的線程使用CPU,如果線程的優(yōu)先級相同會隨機(jī)選擇一個

Thread()類中獲取和設(shè)置優(yōu)先級的方法

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

線程的生命周期

2、實(shí)現(xiàn)Runnable:

  • 定義一個類實(shí)現(xiàn)Runnable接口
  • 在類1中重寫run()方法
  • 創(chuàng)建類1的對象
  • 創(chuàng)建Threa類的對象,把類1對象作為構(gòu)造方法的參數(shù)
  • 啟動線程

代碼示例

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相比,實(shí)現(xiàn)Runnable的好處:

  • 避免了Java單繼承額局限性
  • 適合多個相同程序的代碼處理同一個資源的情況,把線程和程序的代碼、數(shù)據(jù)有效分離,較好的體現(xiàn)了面向?qū)ο蟮乃季S

3、實(shí)現(xiàn) Callable接口(Callable接口有返回值 Runnable接口無返回值),使用ExecutorService、Callable、Future實(shí)現(xiàn)有返回結(jié)果的多線程

示例代碼

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

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //2)創(chuàng)建Callable接口實(shí)現(xiàn)類對象
        CallableDemo callableDemo = new CallableDemo();
        //FutureTask實(shí)現(xiàn)了RunnableFuture接口,RunnableFuture繼承了Runnable接口,F(xiàn)utureTask接口就是Runnable接口的實(shí)現(xiàn)類
        FutureTask<Integer> task = new FutureTask<>(callableDemo);
        Thread thread1 = new Thread(task); //線程池:省去了創(chuàng)建線程、釋放線程的時間
        //3)開啟新的線程
        thread1.start();
        System.out.println("result="+task.get());
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容