溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java多線程中如何創(chuàng)建線程

發(fā)布時(shí)間:2022-02-24 13:42:10 來源:億速云 閱讀:174 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹Java多線程中如何創(chuàng)建線程,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

    一、三種創(chuàng)建方式

    基于什么創(chuàng)建創(chuàng)建的方式
    Thread類繼承Thread
    Runnable接口實(shí)現(xiàn)Runnable接口
    callable接口實(shí)現(xiàn)callable接口

    二、通過Thread類創(chuàng)建

    2.1 步驟

    • 自定義線程類繼承Thread

    • 重寫run()方法,編寫線程執(zhí)行體(當(dāng)成main()方法用)

    • 創(chuàng)建線程對象,調(diào)用start()方法啟動線程

    2.2 案例

    • 創(chuàng)建兩個(gè)線程,其中一個(gè)線程打印100以內(nèi)的偶數(shù),另一個(gè)線程打印100以內(nèi)的奇數(shù)

    //主方法
    public class Demo01 {
        public static void main(String[] args) {
            Thread1 thread1 = new Thread1();
            Thread2 thread2 = new Thread2();
    
            thread1.start();
            thread2.start();
        }
    }
    
    //100以內(nèi)的偶數(shù)
    class Thread1 extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                if (i%2==0){
                    System.out.println(Thread.currentThread().getName() + ":" + i);
                }
            }
        }
    }
    
    //100以內(nèi)的奇數(shù)
    class Thread2 extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                if (i%2!=0){
                    System.out.println(Thread.currentThread().getName() + ":" + i);
                }
            }
        }
    }
    • 也可以使用匿名內(nèi)部類的方法來實(shí)現(xiàn)(線程用過以后就不再用了)

    public class Demo02 {
        public static void main(String[] args) {
            //打印0~100內(nèi)的偶數(shù)
            new Thread(){
                @Override
                public void run() {
                    for (int i = 0; i < 100; i++) {
                        if (i%2==0){
                            System.out.println(Thread.currentThread().getName() + ":" + i);
                        }
                    }
                }
            }.start();
            //打印0~100內(nèi)的奇數(shù)
            new Thread(){
                @Override
                public void run() {
                    for (int i = 0; i < 100; i++) {
                        if (i%2!=0){
                            System.out.println(Thread.currentThread().getName() + ":" + i);
                        }
                    }
                }
            }.start();
        }
    }
    • 三個(gè)窗口同時(shí)賣票,票數(shù)總共為100張(注意票數(shù)應(yīng)該是靜態(tài)變量,否則就是沒創(chuàng)建一個(gè)對象,該對象就有100張票)

    public class Test {
        public static void main(String[] args) {
            Window w1 = new Window("窗口 1 ");
            Window w2 = new Window("窗口 2 ");
            Window w3 = new Window("窗口 3 ");
    
            w1.start();
            w2.start();
            w3.start();
        }
    }
    
    class Window extends Thread{
        //這里票的數(shù)量應(yīng)該是靜態(tài)變量,否則每個(gè)對象創(chuàng)建后都有100張票,而不是總共100張票
        private static int tickets = 100;
    
        public Window(String name) {
            super(name);
        }
    
        @Override
        public void run() {
            while (tickets > 0){
                tickets--;
                System.out.println(getName() + "賣出了一張票,剩余票數(shù):" + tickets);
            }
        }
    }
    • 注意:這里存在一個(gè)線程安全問題未解決,后面將會講到。如下圖所示,剛開始三個(gè)線程啟動的時(shí)候,讀取的票數(shù)都是100張。

    Java多線程中如何創(chuàng)建線程 

    2.3 注意的問題

    • start()方法的作用:通過調(diào)用自己寫的線程類對象的start()方法,來啟動該線程,并調(diào)用該線程的run()方法

    • 不能通過直接調(diào)用run()方法的方式啟動線程

    • 不可以讓已經(jīng)start()的線程再次star()來同時(shí)跑兩個(gè)線程??梢酝ㄟ^新建一個(gè)該線程類的對象,然后在對新建的對象start()

    三、Thread類中常用的方法

    • start()啟動當(dāng)前線程;調(diào)用當(dāng)前線程的run()方法

    • run():通常需要重寫Thread類中的此方法,將創(chuàng)建線程需要執(zhí)行的操作聲明在此方法中(當(dāng)做main()使用)

    • currentThread():靜態(tài)方法,返回執(zhí)行當(dāng)前代碼的線程

    • getName():獲取當(dāng)前線程的名字

    • setName(String name):設(shè)置當(dāng)前線程的名字

    • yield():釋放當(dāng)前CPU的執(zhí)行權(quán)(但也有可能下一刻的執(zhí)行權(quán)又回到了當(dāng)前線程,主控權(quán)還是在CPU手上)

    • join():在線程a中調(diào)用線程bjoin(),此時(shí)線程a就進(jìn)入阻塞狀態(tài),直到線程b完全執(zhí)行完之后,線程a在結(jié)束阻塞狀態(tài)

    • stop():當(dāng)執(zhí)行此方法時(shí),強(qiáng)制結(jié)束當(dāng)前線程(已停用

    • sleep(int millitime):讓當(dāng)前線程“睡眠”指定的millitime毫秒。在指定的millitime毫秒時(shí)間內(nèi),當(dāng)前進(jìn)程是阻塞狀態(tài)

    • isAlive():判斷當(dāng)前線程是否存活(線程執(zhí)行完之前都是存活的)

    3.1 案例

    • 同樣是上面的三個(gè)窗口買票的問題,同樣是100張票,但使用這種創(chuàng)建方法,tickets可以不使用靜態(tài)變量

    Java多線程中如何創(chuàng)建線程

    四、通過實(shí)現(xiàn)Runnable接口來創(chuàng)建線程

    4.1 創(chuàng)建步驟

    • 創(chuàng)建一個(gè)實(shí)現(xiàn)了Runnable接口的類

    • 實(shí)現(xiàn)類去實(shí)現(xiàn)Runnable接口中的抽象方法:run()

    • 創(chuàng)建實(shí)現(xiàn)類的對象

    • 將此對象作為參數(shù)傳遞到Thread類的構(gòu)造器中,創(chuàng)建Thread類的對象

    • 通過Thread類的對象調(diào)用start()

    • 這里的start()首先啟動了當(dāng)前的線程,然后調(diào)用了Runnable類型的target的run()

    Java多線程中如何創(chuàng)建線程

    五、繼承Thread類和實(shí)現(xiàn)Runnable接口兩種方式比較

    開發(fā)中,優(yōu)先選擇實(shí)現(xiàn)Runnable接口的方式創(chuàng)建線程

    原因:

    • 實(shí)現(xiàn)Runnable接口的方式?jīng)]有類的單繼承性的局限性(一個(gè)類只能繼承一個(gè)父類,繼承了Thread類就不能在繼承其他類了)

    • 實(shí)現(xiàn)Runnable接口的方式更適合來處理多個(gè)線程之間有共享數(shù)據(jù)的情況

    聯(lián)系:Thread類本身也實(shí)現(xiàn)了Runnable接口

    Java多線程中如何創(chuàng)建線程

    相同點(diǎn):兩種方式都需要重寫run()方法,將線程要執(zhí)行的邏輯聲明在run()方法中

    六、線程的優(yōu)先級設(shè)置

    調(diào)度策略

    • 對于同優(yōu)先級的線程,組成先入先出隊(duì)列(先到先服務(wù)),使用時(shí)間片策略

    • 對于高優(yōu)先級,使用優(yōu)先調(diào)度的搶占式模式

    線程的優(yōu)先級分為1~10十個(gè)檔,其中:

    • NORM_PRIORITY:5 —— 普通優(yōu)先級,即默認(rèn)的優(yōu)先級

    • MAX_PRIORITY:10 —— 最高優(yōu)先級

    • MIN_PRIORITY:1 —— 最低優(yōu)先級

    • getPriority():獲取線程的優(yōu)先級

    • setPriority(int p):設(shè)置線程的優(yōu)先級

    注意:高優(yōu)先級的線程要搶占低優(yōu)先級線程CPU的執(zhí)行權(quán)。但是只是從概率上來講,高優(yōu)先級的線程高概率的情況下被執(zhí)行。并不意味著只有當(dāng)高優(yōu)先級的線程被執(zhí)行完以后,低優(yōu)先級的線程才會被執(zhí)行。

    以上是“Java多線程中如何創(chuàng)建線程”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI