国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Java系列】詳解多線程(二)——Thread類及常見方法(上篇)

這篇具有很好參考價值的文章主要介紹了【Java系列】詳解多線程(二)——Thread類及常見方法(上篇)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

個人主頁:兜里有顆棉花糖
歡迎 點贊?? 收藏? 留言? 加關(guān)注??本文由 兜里有顆棉花糖 原創(chuàng)
收錄于專欄【Java系列專欄】【JaveEE學(xué)習專欄】
本專欄旨在分享學(xué)習Java的一點學(xué)習心得,歡迎大家在評論區(qū)交流討論??

一、前文回顧

我們先來回顧一下線程與進程之間的聯(lián)系。

我們知道多進程可以幫助我們完成并發(fā)編程,即可以把多個cpu核心充分利用起來以完成同時執(zhí)行多任務(wù)的場景。但是進程有一個問題就是進程的創(chuàng)建和銷毀的開銷是比較大的,如果我們需要頻繁的創(chuàng)建和銷毀進程的話,那么多進程這種方式就是比較低效的。所以就衍生出了輕量級進程——線程。線程之所以比進程更輕量級主要有兩方面的原因

  • 一方面是線程共享進程的資源,不要忘記,線程是進程的一部分,線程可以共享那些屬于進程的資源,但是進程之間是相對獨立的,線程創(chuàng)建時不需要像進程那樣需要分配獨立的資源,因此線程創(chuàng)建和銷毀的開銷會比進程小很多;
  • 另一方面線程調(diào)度切換要比進程調(diào)度切換要快上很多,由于多線程使用的調(diào)度算法比單進程要復(fù)雜很多,加上線程對系統(tǒng)資源的共享(線程在同一個進程內(nèi)共享資源,線程切換只需要切換線程的上下文,而不需要切換整個進程的上下文;而相比之間進程切換需要保存和恢復(fù)進程的所有上下文信息,包括內(nèi)存映像、打開的文件、進程狀態(tài)等。),所以線程調(diào)度之間的切換要比進程調(diào)度的切換快上很多,也更容易實現(xiàn)多任務(wù)的處理。

線程在同一進程內(nèi)共享內(nèi)存資源,所以當進程創(chuàng)建完成時,線程已經(jīng)可以訪問和共享這些內(nèi)存資源(主線程是在進程創(chuàng)建時默認創(chuàng)建的一個線程)。如果后續(xù)需要我們創(chuàng)建其它的線程,我們就可以重用之前的字眼就可以了。

進程包含了線程,一個進程內(nèi)部至少有一個線程,進程是系統(tǒng)中分配資源的基本單位,而線程是cpu調(diào)度執(zhí)行的基本單位。我們可以這樣說線程的引入最主要的就是為了實現(xiàn)更高效的并發(fā)處理和資源共享。

由于線程可以共享同一進程內(nèi)的內(nèi)存資源,因此資源分配的主要任務(wù)是為進程分配足夠的內(nèi)存空間,對線程的資源分配比在進程級別上的資源分配要少得多。

現(xiàn)在問題來了,一個進程內(nèi)既然可以存在多個線程,同時線程可以共享同一個進程內(nèi)的資源,這也意味著這多個線程之間的相互干擾會比較大(這一點就不如進程之間那樣相對獨立一些,一個進程掛掉知道后不會對其它進程產(chǎn)生影響。),一旦某個出現(xiàn)異常之后就有可能導(dǎo)致整個進程都會掛掉,這當然會對其它線程產(chǎn)生影響。另外,多個線程去訪問同一塊公共資源的時候也可能會出現(xiàn)沖突帶來線程安全的問題。

所以,總的來說使用多線程的方式完成任務(wù)比多進程的方式完成任務(wù)會有優(yōu)勢,但同時存在一些缺點。但盡管如此,我們依然可以利用多線程的方式來很好的完成并發(fā)編程的任務(wù)。

好了,友友們,回顧到此結(jié)束,接下來我們一起學(xué)習新的內(nèi)容吧!?。?/strong>

二、創(chuàng)建線程的幾種方式。

Java標準庫中,提供了Thread()類來表示線程,同時Java創(chuàng)建線程的方式有很多種。最常見的兩種寫法:繼承Thread()類、重寫Runnable方法()。

繼承Thread類

方式一:通過繼承thread類來重寫run方法是一種創(chuàng)建線程的方式(這里我們需要自己創(chuàng)建一個類來繼承thread方法);方式二:還有一種方式我們也可以創(chuàng)建線程:基于匿名內(nèi)部類的形式來繼承thread類,并重run方法。

現(xiàn)在我們通過匿名內(nèi)部類的方式來創(chuàng)建線程(基于匿名內(nèi)部類的形式來繼承thread類,并重寫run方法,即方式二):

代碼如下:

public class Demo03 {
    public static void main(String[] args) {
        Thread t = new Thread() {
            @Override
            public void run() {
                while(true) {
                    System.out.println("hello thread!!!");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
        t.start();
    }
}

解釋:上述代碼中我們創(chuàng)建了一個子類,這個子類(此類就是我們說的匿名內(nèi)部類)繼承自Thread類,同時我們在這個子類重對run方法進行了重寫。
另外我們還創(chuàng)建了該子類(也就是之前說的匿名內(nèi)部類)的實例,用引用t類指向這個實例。
最后就是通過引用t來調(diào)用start方法來調(diào)用系統(tǒng)API,再從內(nèi)核中把線程創(chuàng)建出來。
【Java系列】詳解多線程(二)——Thread類及常見方法(上篇),Java系列,JavaEE學(xué)習專欄,java,開發(fā)語言,java-ee
最后我們來看一下運行結(jié)果:
【Java系列】詳解多線程(二)——Thread類及常見方法(上篇),Java系列,JavaEE學(xué)習專欄,java,開發(fā)語言,java-ee

實現(xiàn)runnable方法

方式三通過實現(xiàn)runnable來重寫run方法(這里是自己創(chuàng)建一個類)的方式可以創(chuàng)建一個線程。方式四:另外我們這里依然可以用其它方式來創(chuàng)建一個線程:即基于匿名內(nèi)部類的形式來實現(xiàn)runnable并重寫run方法。

現(xiàn)在我們通過匿名內(nèi)部類的形式來實現(xiàn)runnable并重寫run方法(即方式四)來創(chuàng)建線程,代碼如下:

public class Demo04 {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    System.out.println("hello world");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });
        t.start();
    }
}

解釋,上述代碼中,我們創(chuàng)建了runnable的子類,并重寫了run方法,然后創(chuàng)建出了runnable的子類的實例,把這個實例傳給Thread的構(gòu)造方法。

lambda表達式

我們還可以通過lambda表達式來表示run方法的內(nèi)容,從而創(chuàng)建出線程。

代碼如下:

public class Demo05 {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            while(true) {
                System.out.println("hello world");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();
    }
}

什么是lambda表達式:lambda表達式本質(zhì)上就是一個匿名函數(shù),主要可以用來作為回調(diào)函數(shù)來進行使用。
先來回顧一下回調(diào)函數(shù)吧:回調(diào)函數(shù)不需要我們自己去進行調(diào)用,因為回調(diào)函數(shù)會在特定的時機自動地被調(diào)用。
此時的回調(diào)函數(shù)就是在線程創(chuàng)建成功之后才會真正執(zhí)行。

關(guān)于線程的創(chuàng)建這里,也有其它的方式,比如基于callable的方式創(chuàng)建線程,基于線程池的方式創(chuàng)建線程。

三、Thread類及常見方法

Thread類是JVM用來管理線程的一個類,換句話說,每個線程都有一個唯一的Thread對象與之關(guān)聯(lián)。我們對線程的各種操作都是根據(jù)Thread類進行展開的。

Thread類的常見構(gòu)造方法

這里我們可以參照Java官方文檔:https://docs.oracle.com/javase/8/docs/api/index.html
【Java系列】詳解多線程(二)——Thread類及常見方法(上篇),Java系列,JavaEE學(xué)習專欄,java,開發(fā)語言,java-ee

【Java系列】詳解多線程(二)——Thread類及常見方法(上篇),Java系列,JavaEE學(xué)習專欄,java,開發(fā)語言,java-ee

如下圖的代碼中,我們給線程起了個名字mythread
【Java系列】詳解多線程(二)——Thread類及常見方法(上篇),Java系列,JavaEE學(xué)習專欄,java,開發(fā)語言,java-ee
我們可以通過JVM中的jconsole.exe來看到這個線程(mythread):
【Java系列】詳解多線程(二)——Thread類及常見方法(上篇),Java系列,JavaEE學(xué)習專欄,java,開發(fā)語言,java-ee
現(xiàn)在問題來了,為什么我們沒有看到主線程(main)呢?在上述代碼中,主線程創(chuàng)建并啟動了一個新線程,而新線程負責打印"hello thread"的消息。由于新線程的循環(huán)中有一個線程休眠的操作(Thread.sleep(1000)),所以您將會在不同時間間隔內(nèi)看到"hello thread"的輸出。但這個輸出是由新線程負責的,而不是主線程。
所以,我們沒有看到主線程的原因是主線程沒有顯示任何輸出或執(zhí)行其他代碼來表明它的存在。它僅僅完成了創(chuàng)建和啟動新線程的任務(wù),然后退出。
對于主線程來說,main方法就是主線程的入口;而對于其它線程來說,lambda或者run就是線程的入口。所以執(zhí)行完線程的入口函數(shù),線程就算是結(jié)束了。

Thread類的屬性

下面是Thread類的幾個常見屬性:

屬性 獲取方法
ID getId()
名稱 getName()
狀態(tài) getState()
優(yōu)先級 getPriority()
是否后臺線程 isDasmon()
是否存活 isAlive()
是否被中斷 isInterrupted()
  • ID:這里是JVM給線程設(shè)定的身份標識。對于一個線程來說,身份標識可以有好多個,就像一個人有大名也有小名。比如JVM給某一線程設(shè)定了一個身份標識,phread庫(系統(tǒng)給開發(fā)人員提供的操作線程的API)也有一個線程的身份標識,內(nèi)核中還有一個線程的身份標識,這幾個身份標識之間相互獨立互不干擾。
  • 名稱:設(shè)置線程名稱方便我們知道這個線程是干什么用的,同時也方便我們?nèi)ミM行調(diào)試。
  • 狀態(tài):Java中的線程狀態(tài)和操作系統(tǒng)中的有所區(qū)別,Java中的線程狀態(tài)更加細化。
  • 優(yōu)先級:關(guān)于獲取、設(shè)置線程的優(yōu)先級其實并沒有太大意義,因為系統(tǒng)內(nèi)核進行線程調(diào)度的速度極快(線程調(diào)度是由系統(tǒng)內(nèi)核負責的),快到我們根本無法感知,所有我們一般使用默認的線程優(yōu)先級即可。
  • 是否是后臺線程:后臺線程又稱為守護線程,后臺線程不會影響線程結(jié)束;而前臺線程會影響線程結(jié)束,如果前臺線程沒有執(zhí)行完的話,進程是不會結(jié)束的;一個進程中如果所有的前臺線程都執(zhí)行完此時進程退出,如果此時依然存在后臺線程沒有執(zhí)行完的話,后臺線程依然會隨著進程的退出而退出。我們創(chuàng)建的線程默認是前臺線程。如下代碼進行演示:
// 這里我們創(chuàng)建的線程是前臺線程
public class Demo07 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            while(true) {
                System.out.println("hello thread!!!");
            }
        });
        t.start();
    }
}

// 這里將我們創(chuàng)建的線程設(shè)置為了后臺線程
public class Demo07 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            while(true) {
                System.out.println("hello thread!!!");
            }
        });
        t.setDaemon(true);
        t.start();
    }
}

當我們把創(chuàng)建的線程設(shè)置為后臺線程之后,程序運行起來之后就會立即結(jié)束。原因:由于我們把自己手動的線程創(chuàng)建成了后臺線程,所以此時就只剩下main主線程了,而main線程這里不需要執(zhí)行代碼,所以執(zhí)行時間極短main線程(前臺線程)就結(jié)束了,而我們設(shè)置的后臺線程還沒有來得及執(zhí)行就隨著進程的退出而退出了。

  • 是否存活(isAlive()):這里的存活指的并不是thread對象是否存活,而是指的thread對象(我們也可以稱為線程對象)對應(yīng)的線程(即系統(tǒng)內(nèi)核中的線程)是否存活。Thread對象的聲明周期并不是和系統(tǒng)內(nèi)核中的線程的生命周期完全一致。一般來說都是先把thread對象創(chuàng)建好,然后手動調(diào)用start方法,此時內(nèi)核才真正創(chuàng)建出線程。對于線程,當它的run方法執(zhí)行完后,線程的生命周期也會自然結(jié)束,就算線程對象還存在于內(nèi)存中。此時該線程會釋放占用的資源并進入死亡狀態(tài);還有另外一種情況就是線程對象生命周期的結(jié)束(即沒有引用指向該線程對象了),此時線程也會結(jié)束,這種情況下,線程的run方法執(zhí)行與否并不影響線程的結(jié)束狀態(tài)。垃圾回收器會在適當時候回收無引用的線程對象,并釋放相關(guān)資源。

好了,本文到這里就結(jié)束了,希望友友們可以支持一下一鍵三連哈。嗯,就到這里吧,再見啦?。?!

【Java系列】詳解多線程(二)——Thread類及常見方法(上篇),Java系列,JavaEE學(xué)習專欄,java,開發(fā)語言,java-ee文章來源地址http://www.zghlxwxcb.cn/news/detail-755947.html

到了這里,關(guān)于【Java系列】詳解多線程(二)——Thread類及常見方法(上篇)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包