Java 併發編程解析 | 每個Java Developer都應該知道的關於併發編程的那點事?

蒼穹之邊,浩瀚之摯,眰恦之美; 悟心悟性,善始善終,惟善惟道! —— 朝槿《朝槿兮年說》

寫在開頭

在這個互聯網應用亂象叢生的時代,應對複雜業務需求,如何開發和設計一個高效和穩定的應用程序,一直都是我們備受矚目的關注點 。作爲一名Java Developer,從接觸 Java 開發到現在,相信大家對於併發編程這個概念都不陌生,你對 Java併發編程最直觀的印象是什麼呢?是各個大廠面試寶典宣揚的高頻熱詞,還是在實際工作中,都有過實際工作場景必備高階開發技術?關於併發編程的基礎和原則都做到了然於胸了嗎?接下來,我們一起總結和思考一下。

併發編程三要素

所謂併發編程是指在一臺處理器上“同時”處理多個任務。併發是在同一實體上的多個事件。多個事件在同一時間間隔發生。——百度百科

對於時實際編程過程中,其實相當一大部分的任務都是可以通過順序編程來解決,只是對於某些特殊的和特定的問題,併發編程會讓我們對於應用程序的操作與控制可以變得十分方便甚至必要。很大程度上說,併發編程"具有可論證的確定性,但是實際上也具有不可確定性“,正是因爲如此,併發編程令人最困惑的一個原因:使用併發時需要解決的問題有多個,而實現併發的方式也有多種,並且兩者之間沒有十分明顯的映射關係。從併發編程幫助我們解決問題來說,主要是應用程序“運行速度”和“設計可管理性”兩個方面。

從而我們知道,併發編程三要素主要是指原子性,可見性,有序性,其中:

  1. 原子性:最小粒度的劃分,即一個不可被分割的操作。Java 中的原子性指:一個或多個操作要麼全部執行成功,要麼全部執行失敗。
  2. 有序性:程序執行的順序是按照代碼的先後順序執行的。cpu 有可能會對指令進行重排序。
  3. 可見性:當多個線程訪問同一個共享變量時,如果其中一個線程對其進行了修改操作,其它線程能立即獲取到最新修改的值。

綜上所述,併發的本質本身是提高運行在單處理器上的程序的性能,實現併發最直接的方式是在操作系統級別使用進程,操作系統會自動隔離資源。但是對於像Java這樣的會共享資源來說,在協調不同線程驅動的任務之間的資源使用,會使得某些資源無法被多個任務訪問。因此,Java在順序編程的基礎上,支持對線程的控制,而且只對操作系統透明。

“X”程基本概述

在Java中,我們都知道應用程序(Application Program)的代碼會被裝載並且放入一個class裏面,最後保存到一個拓展名爲.java的文件中,然後通過命令工具和開發環境的編譯,生成.class文件,最終託管給JVM虛擬機運行起來,從而實現我們要的反饋結果。在這些操作過程中,我們需要理解程序,進程,線程等幾個關鍵概念,其中:

  1. 程序(Program):指一組指示計算機或其他具有信息處理能力裝置執行動作或做出判斷的指令,通常用某種程序設計語言編寫,運行於某種目標計算機體系結構上。
  2. 進程(Process):計算機中的軟件程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎,是系統分配資源和調度的基本單位,也就是說進程可以單獨運行一段程序。
  3. 線程(Thead):進程中的一個實體,是被系統獨立調度和分派的基本單位,是CPU調度和分派的最小基本單位,線程自己不擁有操作系統資源,但是該線程可與同屬進程的其他線程共享該進程所擁有的全部資源。

從一定程度上來說,進程是程序的實體,而線程又是進程的實體,進程又是線程的容器。三者之間區別如下:

  • 對於程序而言,程序並不能單獨執行,是靜止的,只有將程序加載到內存中,系統爲其分配資源後才能夠執行。
  • 對於進程而言,程序對一個數據集的動態執行過程,一個進程包含一個或者更多的線程,一個線程同時只能被一個進程所擁有,進程是分配資源的基本單位。進程擁有獨立的內存單元,而多個線程共享內存,從而提高了應用程序的運行效率。
  • 對於線程而言,線程是進程內的基本調度單位,線程的劃分尺度小於進程,併發性更高,線程本身不擁有系統資源,但是該線程可與同屬進其他線程共享該進程所擁有的全部資源。每一個獨立的線程,都有一個程序運行的入口、順序執行序列和程序的出口。

綜上所述,每個應用程序都使用一塊內存區域,這個內存區域可以稱爲一個進程,內存區域中是需要執行代碼的,具體執行代碼就是線程去執行的。 需要注意的是:進程只是負責開闢內存空間的,線程纔是負責執行代碼邏輯的執行單元。

除了線程和進程外,我們更需要了解什麼是管程,協程和纖程:
1.管程(Monitors):提供了一種機制,線程可以臨時放棄互斥訪問,等待某些條件得到滿足後,重新獲得執行權恢復它的互斥訪問。
2.纖程(Fiber):是Microsoft組織爲了幫助企業程序的更好移植到Windows系統,而在操做系統中增加的一個概念,由操作系統內核根據對應的調度算法進行控制,也是一種輕量級的線程。
3.協程(Coroutines):一種基於線程之上,但又比線程更加輕量級的存在,這種由程序管理的輕量級線程也被稱爲用戶空間線程,對於內核而言是不可見的。正如同進程中存在多條線程一樣,線程中也可以存在多個協程。協程在運行時也有自己的寄存器、上下文和棧,協程的調度完全由用戶控制,協程調度切換時,會將寄存器上下文和棧保存到分配的私有內存區域中,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操作棧則基本沒有內核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非常快。

⚠️[特別關注]:
1.纖程和協程的概念一致,都是線程的多對一模型,但有些地方會區分開來,但從協程的本質概念上來談:纖程、綠色線程、微線程這些概念都屬於協程的範圍。
2. 2.纖程和協程的區別在於:纖程是OS級別的實現,而協程是語言級別的實現,纖程被OS內核控制,協程對於內核而言不可見。

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