Java多執行緒概念簡介 多執行緒中篇(一)
線上程的相關介紹中,有講到“執行緒的實現”分為三種:核心支援,使用者級以及兩者混合。(這只是一種簡要的分類)
Java執行緒在JDK1.2之前,是使用者執行緒實現的
而在JDK1.2中,執行緒模型變為基於作業系統原生執行緒模型來實現的
所以說Java虛擬機器中執行緒的對映實現,是受制於作業系統的,作業系統支援怎樣的執行緒模型,決定了Java虛擬機器中執行緒的樣子。
虛擬機器規範中也並未限定Java執行緒需要使用哪種執行緒模型來實現。
執行緒模型只對執行緒的併發規模和操作成本產生影響,對Java程式的編碼和執行過程來說,這些差異都是透明的。
目前因為Windows和Linux系統提供的執行緒模型就是一對一的,所以對於Sun JDK來說,它的Windows版與Linux版都是使用一對一的執行緒模型實現的,一條Java執行緒就對映到一條輕量級程序之中
簡言之,現在的JDK執行緒模型基於作業系統原生執行緒,所以模型依賴於作業系統對執行緒的支援,另外Windows和Linux系統提供的執行緒模型就是一對一的
所以可以簡單認為:
現在Java執行緒與作業系統執行緒一對一對映
現在的Java執行緒,就是作業系統中的執行緒
至於JVM將Java執行緒與作業系統的執行緒是如何對映的?不同的作業系統中具體的執行緒是如何實現的?是另外的兩個很深的問題。
之所以提到Java執行緒與作業系統執行緒,其實是想說,作業系統中將程式的執行抽象為程序和執行緒,有一套抽象的理論體系,其實Java執行緒與他們是同根同源的,核心思維邏輯是相同的,所以前面簡單瞭解到的作業系統對於程序、執行緒的相關內容,並不是那麼的廢話..... ̄□ ̄||
不過儘管相似之處太多太多,雖同根同源,但是卻又千差萬別,每個人從生物的角度來說,骨骼多少塊?肌肉多少塊?幾隻眼睛?幾隻耳朵?..儘管這都是相同的,但是每個人真的一樣麼,脾氣?秉性?能力?...
一切都是Thread
Thread是Java對執行緒的抽象描述,所以多執行緒程式設計模型必然是針對Thread
不管JVM與作業系統的執行緒到底如何對映,到底如何執行,面對Java,程式設計師看到的就只是Thread
程式碼中操作的這個Thread類的例項,就好比是作業系統底層執行緒的一個指標(控制代碼),你想這個執行緒怎麼樣,通過操作這個Thread例項物件即可
拋開之前篇章中關於作業系統、程序、執行緒、同步、控制、死鎖等底層基礎知識的介紹,從Java多執行緒程式設計的視角看,我們就是在操縱不同的Thread物件例項,對這些例項進行不同的配置,並且讓他們相互協作。
Thread是一個類,用於描述了執行緒這一概念,Thread有自身的屬性資訊比如名稱,這些屬性資訊用於描述執行緒本身或者用於支撐執行緒可以操作的行為。
如同我們定義一個Person類,這個類擁有一些屬性和方法,然後定義了一些例項物件進行協作。
多執行緒開發就是操縱Thread物件
Java多執行緒程式開發中,程式設計師建立Thread類的例項,並且對例項進行配置,然後通過可操作的行為方法對他們進行管理排程,使程式以多執行緒的形式執行
在神話故事中,女媧娘娘摶土造人,每一個人都是“人類”的一個例項,每個人有姓名性別等屬性資訊,“人類”有自身的能力(行走,說話,思考,認知等),通過後天的努力學習也都有各自的能力(執行緒任務),整個世界由一個個不同的人,整個社會的活動由所有的人的相互的行為互動構成。
對於Java多執行緒程式開發中的程式設計師們來說,不就相當於神話故事中的女媧娘娘麼
整個多執行緒的世界裡面,都是Thread的例項物件,程式設計師負責建立、配置、管理排程這些物件,也就形成了支援多執行緒的程式了。
儘管多執行緒程式設計非常繁瑣、複雜、易錯,但是如果理解清楚了Thread的抽象模型,並且對多執行緒程式設計模型中的解決思路熟悉,就能夠編寫出來良好的多執行緒程式。
Thread的抽象模型往簡單了說就是Thread這個類,他有屬性欄位,有public方法,也有封裝到執行緒任務(Runnable),對於一個Thread的設定,他就那些可配置專案,不多不少
所以只要你理解了Thread的的抽象模型,那麼你就能夠很清晰的對你需要的Thread進行配置。
而多執行緒程式設計模型中的解決思路就如同下棋時的套路那般,可以讓你更好更快更全面的寫出來多執行緒應用程式。
所以說,什麼是Java多執行緒程式設計?
只有兩個步驟, 建立Thread 物件,使用Thread物件 ,看起來似乎是超乎尋常的簡單
使用電腦也很簡單,按下電源鍵開機,使用滑鼠和鍵盤,說起來也是非常的簡單,但是使用計算機完成工作任務,卻不是一件輕鬆的事情。
多執行緒不巧的是,也是如此,首先多執行緒程式設計模型的概念源於作業系統中的多執行緒(程序),然後有千差萬別,所以對於Thread抽象模型的理解本身就具有一定的門檻
另外,對於執行緒的操作有多種方法,既然是多執行緒就不止一個執行緒,那麼多執行緒、多互動方法,必然產生很多種複雜的協作邏輯,如何能夠正確高效的組織,也是非常考驗智商的。
Java執行緒邏輯
作業系統中我們對程序進行了介紹,對於程序作為作業系統對於程式執行的抽象,核心為 程序控制、程序同步、程序通訊
我們前面有說到Java多執行緒與作業系統中的執行緒(程序)同根同源,其實Java的多執行緒程式設計模型核心也是這三部分
- 對於Thread類本身,擁有其自身的屬性,比如名字、Id、優先順序、狀態等,這就是程序的控制資訊;
- 對於Thread中封裝的任務,Java提供了synchronized,volatile關鍵字用於控制共享資源的訪問,這就是程序的同步;
- 對於Thread中的一些行為(以及從Object繼承而來的),比如join、wait則相當於程序的通訊;
簡言之,Java中對作業系統中的程序的控制、同步、通訊,都有抽象,當然對於Java執行緒來說,從程式設計的角度看,他的主宰不是作業系統而是我們程式設計師。
所以說繞來繞去,即使我們說的是Java中的多執行緒,還是繞不開“控制、同步、通訊”的概念。
Java多執行緒程式設計到底是什麼
所以說了這麼多,到底Java多執行緒程式設計到底是什麼?我們前面說只有兩個步驟“建立Thread 物件,使用Thread物件”
這兩個部分是對執行緒本身的控制與處理,但是在使用Thread物件時,還有一個最重要的部分,也就是為什麼我們要使用執行緒?
還不是為了執行任務?
所以說,任務的執行也是非常重要的程式碼,因為,多執行緒中的程式碼不再是簡簡單單的完成任務那麼簡單,因為如果涉及到共享資源的訪問,所以就是涉及到程序同步的問題。
所以想要學習Java多執行緒,第一個部分,理解清楚Java對執行緒概念的抽象以及Thread支援的控制操作方法---也就是Thread類本身。
第二個部分,理解清楚Java中同步的邏輯,也就是同步關鍵字的透徹理解。
第三個部分,理解清楚Java對於執行緒通訊的抽象,也就是相關方法比如wait 的邏輯
以上三個部分就是Java多執行緒的基礎,如果真的徹底理解了,我相信任何人都可以寫出正確的多執行緒程式碼。
但是,誰會非要從鍊鋼開始造汽車?電腦城中組裝電腦的店鋪一大把,誰會自己組裝一個CPU或者風扇?
發展到如今,Java也提供了更多的“工具類”,也不斷有一些好的設計模式與理念產生,所以,想要真的成為大師,你還要學會用好各種工具,站在前人的肩膀上。
所以,多執行緒程式設計的學習如上內容。
在上篇中,對作業系統中關於程序執行緒的相關概念進行了簡單介紹,以有助於下一步能夠快速理解Thread抽象模型
在中篇中,將會詳細介紹Java的多執行緒程式設計基礎。
在下篇中將會對多執行緒程式設計中的經典模式、工具類進行簡單介紹。
總結
Java執行緒與作業系統執行緒的概念是同根同源的,根本邏輯是一致的,如同你跟另外一個人,生物上看都是“人類“,儘管從另外的很多角度你們是千差萬別的。
作業系統是為了多程式(任務)的併發執行,所以有了程序抽象概念,為了程式內部更好的併發執行 ,所以有了執行緒的概念。
他們都是圍繞著併發、提高處理機利用率等目的,他們面對的問題也都是相似的,控制、同步、通訊。
所以Java執行緒也不例外,Java執行緒與作業系統關於併發程式程序的相關概念與解決思路也是相通的
所以Java執行緒對作業系統中的概念進行了抽象,通過Thread類提供的屬性和方法,通過關鍵字,通過Object的通訊方法,完成了對程序概念的完整描述。
所以,回頭再看作業系統中關於控制、同步、通訊的內容,你又會覺得非常有幫助。
多執行緒的學習很複雜,如果只是知識點的學習記憶,其實毫無用處,因為首先你不會如此深入底層原語(比如直接使用wait),因為有太多封裝好的類,所以很快你就會忘記了,對於深度封裝的類,不瞭解基礎又無法深入,所以根本就學不會多執行緒。
以上純屬一家之言,如果有理解錯誤的地方,歡迎文明指正。
原文地址: Java多執行緒概念簡介 多執行緒中篇(一)