線程基本概念以及線程的五種狀態、生命週期和線程的創建方式

基本概念

線程:是進程中的一個執行控制單元,執行路徑

  一個進程中至少有一個線程在負責控制程序的執行

  一個進程中如果只有一個執行路徑,這個程序稱爲單線程

  一個進程中有多個執行路徑時,這個程序成爲多線程

一個線程是進程的一個順序執行流。同類的多個線程共享一塊內存空間和一組系統資源,線程本身有一個供程序執行時的堆棧。線程在切換時負荷小,因此,線程也被稱爲輕負荷進程。一個進程中可以包含多個線程。

在JVM內存模型中,線程開闢在棧中,有些前輩稱之爲方法的棧幀,對於這個棧幀空間就是一個線程空間,也就是一個進程調用了一個方法,這個方法在棧中就開闢一個空間,也可以認爲是線程的空間,當該方法結束後,該線程就結束,但進程還在繼續執行,還會繼續執行接下來的方法,繼續開闢線程。。。

線程與進程區別

一個進程有一個或多個線程。線程更細化於進程,使得多線程程序的併發性高。進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。

線程在執行過程中與進程的區別在於每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。

從邏輯角度來看,多線程的意義在於一個應用程序中,有多個執行部分可以同時執行。但操作系統並沒有將多個線程看做多個獨立的應用來實現進程的調度和管理以及資源分配。

一.線程的生命週期及五種基本狀態

關於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()方法,該線程結束生命週期。

二. Java多線程的就緒、運行和死亡狀態

就緒狀態轉換爲運行狀態:當此線程得到處理器資源;

運行狀態轉換爲就緒狀態:當此線程主動調用yield()方法或在運行過程中失去處理器資源。

運行狀態轉換爲死亡狀態:當此線程線程執行體執行完畢或發生了異常。

此處需要特別注意的是:當調用線程的yield()方法時,線程從運行狀態轉換爲就緒狀態,但接下來CPU調度就緒狀態中的哪個線程具有一定的隨機性,因此,可能會出現A線程調用了yield()方法後,接下來CPU仍然調度了A線程的情況。

2.線程創建有幾種方式

1)繼承Thread類創建線程

2)實現Runnable接口創建線程

3)使用Callable和Future創建線程

--------------------------------------三種創建線程方法對比--------------------------------------

實現Runnable和實現Callable接口的方式基本相同,不過是後者執行call()方法有返回值,後者線程執行體run()方法無返回值,因此可以把這兩種方式歸爲一種這種方式與繼承Thread類的方法之間的差別如下:

1、線程只是實現Runnable或實現Callable接口,還可以繼承其他類。

2、這種方式下,多個線程可以共享一個target對象,非常適合多線程處理同一份資源的情形。

3、但是編程稍微複雜,如果需要訪問當前線程,必須調用Thread.currentThread()方法。

4、繼承Thread類的線程類不能再繼承其他父類(Java單繼承決定)。

注:一般推薦採用實現接口的方式來創建多線程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章