Java多線程(二)線程的創建及線程的生命周期

在多線程(一)中,我們簡要地介紹了線程基本知識,下面主要介紹創建線程的兩種方法,并分析線程的幾種基本狀態。

創建線程的兩種方法##

第一種 是將類聲明成Thread的子類的方式####

該子類必須重寫 Thread 類的 run 方法,接下來new這個對象的實例。然后調用start()方法創建并啟動線程。需要注意的是:程序是在調用start()方法之后,才開辟了一個子線程,并執行run方法。如果你直接調run方法(比如在main方法最下面寫上m1.run();),它就是在主線程中執行的,而且是要比開辟三個線程要快的,這就說明新線程創建的過程不會阻塞主線程的后續執行。
多線程最經典例子:售票系統。

public class Test {
    public static void main(String[] args) {
        MyTicketThread m1= new MyTicketThread("1 號售票窗口");
        MyTicketThread m2= new MyTicketThread("2 號售票窗口");
        MyTicketThread m3= new MyTicketThread("3 號售票窗口");
        m1.start();
        m2.start();
        m3.start();
    }
}
class MyTicketThread extends Thread {
    private int ticket = 8; // 8張票
    private String ticketWindowName; // 賣票窗口

    public MyTicketThread(String ticketWindowName) {
        this.ticketWindowName = ticketWindowName;
    }
    @Override
    public void run(){
        for(int i = 0;i < 100; i++){
            if(this.ticket > 0){
                System.out.println(this.ticketWindowName + "賣票---->" + (this.ticket--));
            }
        }
    }
}

注意:同一個Thread不能重復調用start方法,會出現java.lang.IllegalThreadStateException異常。

可以看到三條線程正在并發執行(電腦配置較好的,效果不明顯,要多運行幾次)。可以看到每個窗口都賣了8張票,這符合賣票的邏輯么?接著讓我們看看實現Runnable接口的并發方式。

1 號售票窗口賣票---->8
1 號售票窗口賣票---->7
1 號售票窗口賣票---->6
1 號售票窗口賣票---->5
2 號售票窗口賣票---->8
2 號售票窗口賣票---->7
2 號售票窗口賣票---->6
2 號售票窗口賣票---->5
2 號售票窗口賣票---->4
2 號售票窗口賣票---->3
2 號售票窗口賣票---->2
2 號售票窗口賣票---->1
1 號售票窗口賣票---->4
1 號售票窗口賣票---->3
1 號售票窗口賣票---->2
1 號售票窗口賣票---->1
3 號售票窗口賣票---->8
3 號售票窗口賣票---->7
3 號售票窗口賣票---->6
3 號售票窗口賣票---->5
3 號售票窗口賣票---->4
3 號售票窗口賣票---->3
3 號售票窗口賣票---->2
3 號售票窗口賣票---->1

第二種 通過實現Runnable接口的方式####

重寫run()方法,然后調用new Thread(runnable)的方式創建一個線程,然后調用start()方法啟動線程。

public class TestRunnable {
    public static void main(String[] args) {

        MyThread myThread = new MyThread();
        Thread t1 = new Thread( myThread, "1 號售票窗口");
        Thread t2 = new Thread( myThread, "2 號售票窗口");
        Thread t3 = new Thread( myThread, "3 號售票窗口");
        t1.start();
        t2.start();
        t3.start();
    }
}
class MyThread implements Runnable{
    private int ticket = 8; // 還是8張票
    private String ticketWindowName; // 售票窗口
    @Override
    public void run(){
        for(int i = 0;i < 100; i++){
            if(this.ticket>0){
                System.out.println(Thread.currentThread().getName() + "賣票---->" + (this.ticket--));
            }
        }
    }
}

注意:Runnable接口只能通過Thread的靜態方法Thread.currentThread()取得當前的Thread對象,再調用getName()方法,來取得當前線程的名字。

可以看到是三個售票窗口共同把八張票賣完了。

1 號售票窗口賣票---->8
1 號售票窗口賣票---->6
1 號售票窗口賣票---->5
1 號售票窗口賣票---->4
3 號售票窗口賣票---->3
3 號售票窗口賣票---->1
2 號售票窗口賣票---->7
1 號售票窗口賣票---->2

兩種方式的結果為什么會不同呢?####

第一種,MyTicketThread繼承Thread類的,我們是創建了三個MyTicketThread的實例,同時開辟了三個線程,讓三個售票窗口都去執行“賣8張票”的任務,他們是各自賣各自的票,最后都賣完了8張票。

第二種實現Runnable的, 我們是創建了一個MyThread的實例,相當于建了“賣8張票”的任務,下面開辟了三個線程,相當于三個售票窗口去執行這個任務。

其實這完全是兩個不同的方式來實現多線程,一個是多個線程分別完成自己的任務,一個是多個線程共同完成一個任務。

實現Runnable接口比繼承Thread類所具有的優勢:####

  1. 適合多個相同的程序代碼的線程去處理同一個資源。
  2. 增加程序的健壯性,代碼可以被多個線程共享,代碼和數據獨立。

這種情況下第二種是很好的選擇,但是目前他也是不安全的,我們這里才8張票而已,如果是成千上萬張票呢?下面的博客我們會繼續優化這個例子。

線程的不同狀態即線程的生命周期###

我們每次運行上面的例子,三個線程的執行順序都不一樣,這是為什么呢?這是因為執行start方法的調用后,并不是立即執行多線程代碼,而是使得該線程變為可運行狀態(Runnable),什么時候運行是由操作系統決定的。此時三個線程都在爭奪系統資源,誰先運行,還真不一定。實際上所有的多線程代碼執行順序都是不確定的,每次執行的結果都是隨機的。從這里我們引申出線程的不同的運行狀態,詳見下圖。

Snip20170316_1.png

  1. 新建狀態(New):新創建了一個線程對象。
  2. 就緒狀態(Runnable):線程對象創建后,其他線程調用了該對象的start()方法。該狀態的線程位于可運行線程池中,變得可運行,等待獲取CPU的使用權。
  3. 運行狀態(Running):就緒狀態的線程獲取了CPU,執行程序代碼。
  4. 阻塞狀態(Blocked):阻塞狀態是線程因為某種原因放棄CPU使用權,暫時停止運行。直到線程進入就緒狀態,才有機會轉到運行狀態。阻塞的情況分三種:
    (一)、等待阻塞:運行的線程執行wait()方法,JVM會把該線程放入等待池中。(wait會釋放持有的鎖)
    (二)、同步阻塞:運行的線程在獲取對象的同步鎖時,若該同步鎖被別的線程占用,則JVM會把該線程放入鎖池中。
    (三)、其他阻塞:運行的線程執行sleep()或join()方法,或者發出了I/O請求時,JVM會把該線程置為阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉入就緒狀態。(注意,sleep是不會釋放持有的鎖)
  5. 死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命周期。

在后面更新中,我們會結合具體事例,詳細介紹阻塞狀態下各種方法的用法。
寫完嘍!ㄟ(▔,▔)ㄏㄟ(▔,▔)ㄏㄟ(▔,▔)ㄏ


知識重在總結和梳理,只有不斷地去學習并運用,才能化為自己的東西。當你能為別人講明白的時候,說明自己已經掌握了。

歡迎轉載,轉載請注明出處!

如果有錯誤的地方,或者有您的見解,還請不嗇賜教!

喜歡的話,麻煩點個贊!

Java中的多線程(三)關于多線程管理的相關函數說明
Java中的多線程(一)多線程基礎之進程、線程、并發、并行。
參考文章:http://www.cnblogs.com/GarfieldEr007/p/5746362.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,983評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,772評論 3 422
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,947評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,201評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,960評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,350評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,406評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,549評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,104評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,914評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,089評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,647評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,340評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,753評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,007評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,834評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,106評論 2 375

推薦閱讀更多精彩內容

  • 本文主要講了java中多線程的使用方法、線程同步、線程數據傳遞、線程狀態及相應的一些線程函數用法、概述等。 首先講...
    李欣陽閱讀 2,477評論 1 15
  • 一、線程的生命周期 線程狀態轉換圖: 1、新建狀態 用new關鍵字和Thread類或其子類建立一個線程對象后,該線...
    我是嘻哈大哥閱讀 929評論 0 8
  • Java多線程學習 [-] 一擴展javalangThread類 二實現javalangRunnable接口 三T...
    影馳閱讀 2,977評論 1 18
  • 寫在前面的話: 這篇博客是我從這里“轉載”的,為什么轉載兩個字加“”呢?因為這絕不是簡單的復制粘貼,我花了五六個小...
    SmartSean閱讀 4,770評論 12 45
  • 老枝差互,寂寞秋聲聽徹骨。 明滅街燈,死巷吹寒梧葉風。 乾坤無話,沉霧如籠詩者啞。 且隱癡情。著夢斜簪三兩星。 (...
    梧鳴閱讀 317評論 7 8