1. 程式人生 > >Java 多線程系列2——多線程的生命周期及生產消費者模型

Java 多線程系列2——多線程的生命周期及生產消費者模型

wait 重要 strong clas 經典 關於 running 結束 準備

一、線程的生命周期及五種基本狀態

關於Java中線程的生命周期,首先看一下下面這張較為經典的圖:

技術分享

上圖中基本上囊括了Java中多線程各重要知識點。掌握了上圖中的各知識點,Java中的多線程也就基本上掌握了。主要包括:

Java線程具有五中基本狀態

新建狀態(New):當線程對象對創建後,即進入了新建狀態,如:Thread t = new MyThread();

就緒狀態(Runnable):當調用線程對象的start()方法(t.start();),線程即進入就緒狀態。處於就緒狀態的線程,只是說明此線程已經做好了準備,隨時等待CPU調度執行,並不是說執行了t.start()此線程立即就會執行;

運行狀態(Running):當CPU開始調度處於就緒狀態的線程時,此時線程才得以真正執行,即進入到運行狀態。註:就 緒狀態是進入到運行狀態的唯一入口,也就是說,線程要想進入運行狀態執行,首先必須處於就緒狀態中;

阻塞狀態(Blocked):處於運行狀態中的線程由於某種原因,暫時放棄對CPU的使用權,停止執行,此時進入阻塞狀態,直到其進入到就緒狀態,才 有機會再次被CPU調用以進入到運行狀態。根據阻塞產生的原因不同,阻塞狀態又可以分為三種:

1.等待阻塞:運行狀態中的線程執行wait()方法,使本線程進入到等待阻塞狀態;

2.同步阻塞 -- 線程在獲取synchronized同步鎖失敗(因為鎖被其它線程所占用),它會進入同步阻塞狀態;

3.其他阻塞 -- 通過調用線程的sleep()或join()或發出了I/O請求時,線程會進入到阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉入就緒狀態。

死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命周期。

二、生產——消費者模型

對於多線程程序來說,生產者和消費者模型是比較最經典的。

實際上準確說應該是“生產者-消費者-倉儲”模型。

對於此模型,應該明確一下幾點:

1、生產者僅僅在倉儲未滿時候生產,倉滿則停止生產。

2、消費者僅僅在倉儲有產品時候才能消費,倉空則等待。

3、當消費者發現倉儲沒產品可消費時候會通知生產者生產。

4、生產者在生產出可消費產品時候,應該通知等待的消費者去消費。

下面采用隊列來實現生產消費者模型

技術分享

生產者:

技術分享

消費者

技術分享

生產消費模型:

技術分享

運行結果:

從結果可以看出先進入隊列的先被消費

大家應該註意到其中有一個關鍵詞synchronized

當它用來修飾一個方法或者一個代碼塊的時候,能夠保證在同一時刻最多只有一個線程執行該段代碼。

它有如下特性:

一、當兩個並發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊以後才能執行該代碼塊。

二、然而,當一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。

三、尤其關鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時,其他線程對object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。

技術分享

Java 多線程系列2——多線程的生命周期及生產消費者模型