在這個互聯(lián)網(wǎng)應(yīng)用亂象叢生的時代,應(yīng)對復(fù)雜業(yè)務(wù)需求,如何開發(fā)和設(shè)計一個高效和穩(wěn)定的應(yīng)用程序,一直都是我們備受矚目的關(guān)注點 。作為一名Java Developer,從接觸 Java 開發(fā)到現(xiàn)在,相信大家對于并發(fā)編程這個概念都不陌生,你對 Java并發(fā)編程最直觀的印象是什么呢?是各個大廠面試寶典宣揚的高頻熱詞,還是在實際工作中,都有過實際工作場景必備高階開發(fā)技術(shù)?關(guān)于并發(fā)編程的基礎(chǔ)和原則都做到了然于胸了嗎?接下來,我們一起總結(jié)和思考一下。
并發(fā)編程三要素
所謂并發(fā)編程是指在一臺處理器上“同時”處理多個任務(wù)。并發(fā)是在同一實體上的多個事件。多個事件在同一時間間隔發(fā)生。——百度百科
對于時實際編程過程中,其實相當(dāng)一大部分的任務(wù)都是可以通過順序編程來解決,只是對于某些特殊的和特定的問題,并發(fā)編程會讓我們對于應(yīng)用程序的操作與控制可以變得十分方便甚至必要。很大程度上說,并發(fā)編程"具有可論證的確定性,但是實際上也具有不可確定性“,正是因為如此,并發(fā)編程令人最困惑的一個原因:使用并發(fā)時需要解決的問題有多個,而實現(xiàn)并發(fā)的方式也有多種,并且兩者之間沒有十分明顯的映射關(guān)系。從并發(fā)編程幫助我們解決問題來說,主要是應(yīng)用程序“運行速度”和“設(shè)計可管理性”兩個方面。
從而我們知道,并發(fā)編程三要素主要是指原子性,可見性,有序性,其中:
原子性:最小粒度的劃分,即一個不可被分割的操作。Java 中的原子性指:一個或多個操作要么全部執(zhí)行成功,要么全部執(zhí)行失敗。
有序性:程序執(zhí)行的順序是按照代碼的先后順序執(zhí)行的。cpu 有可能會對指令進(jìn)行重排序。
可見性:當(dāng)多個線程訪問同一個共享變量時,如果其中一個線程對其進(jìn)行了修改操作,其它線程能立即獲取到最新修改的值。
綜上所述,并發(fā)的本質(zhì)本身是提高運行在單處理器上的程序的性能,實現(xiàn)并發(fā)最直接的方式是在操作系統(tǒng)級別使用進(jìn)程,操作系統(tǒng)會自動隔離資源。但是對于像Java這樣的會共享資源來說,在協(xié)調(diào)不同線程驅(qū)動的任務(wù)之間的資源使用,會使得某些資源無法被多個任務(wù)訪問。因此,Java在順序編程的基礎(chǔ)上,支持對線程的控制,而且只對操作系統(tǒng)透明。
“X”程基本概述
在Java中,我們都知道應(yīng)用程序(Application Program)的代碼會被裝載并且放入一個class里面,最后保存到一個拓展名為.java的文件中,然后通過命令工具和開發(fā)環(huán)境的編譯,生成.class文件,最終托管給JVM虛擬機運行起來,從而實現(xiàn)我們要的反饋結(jié)果。在這些操作過程中,我們需要理解程序,進(jìn)程,線程等幾個關(guān)鍵概念,其中:
程序(Program):指一組指示計算機或其他具有信息處理能力裝置執(zhí)行動作或做出判斷的指令,通常用某種程序設(shè)計語言編寫,運行于某種目標(biāo)計算機體系結(jié)構(gòu)上。
進(jìn)程(Process):計算機中的軟件程序關(guān)于某數(shù)據(jù)集合上的一次運行活動,是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位,是操作系統(tǒng)結(jié)構(gòu)的基礎(chǔ),是系統(tǒng)分配資源和調(diào)度的基本單位,也就是說進(jìn)程可以單獨運行一段程序。
線程(Thead):進(jìn)程中的一個實體,是被系統(tǒng)獨立調(diào)度和分派的基本單位,是CPU調(diào)度和分派的最小基本單位,線程自己不擁有操作系統(tǒng)資源,但是該線程可與同屬進(jìn)程的其他線程共享該進(jìn)程所擁有的全部資源。
從一定程度上來說,進(jìn)程是程序的實體,而線程又是進(jìn)程的實體,進(jìn)程又是線程的容器。三者之間區(qū)別如下:
對于程序而言,程序并不能單獨執(zhí)行,是靜止的,只有將程序加載到內(nèi)存中,系統(tǒng)為其分配資源后才能夠執(zhí)行。
對于進(jìn)程而言,程序?qū)σ粋€數(shù)據(jù)集的動態(tài)執(zhí)行過程,一個進(jìn)程包含一個或者更多的線程,一個線程同時只能被一個進(jìn)程所擁有,進(jìn)程是分配資源的基本單位。進(jìn)程擁有獨立的內(nèi)存單元,而多個線程共享內(nèi)存,從而提高了應(yīng)用程序的運行效率。
對于線程而言,線程是進(jìn)程內(nèi)的基本調(diào)度單位,線程的劃分尺度小于進(jìn)程,并發(fā)性更高,線程本身不擁有系統(tǒng)資源,但是該線程可與同屬進(jìn)其他線程共享該進(jìn)程所擁有的全部資源。每一個獨立的線程,都有一個程序運行的入口、順序執(zhí)行序列和程序的出口。
綜上所述,每個應(yīng)用程序都使用一塊內(nèi)存區(qū)域,這個內(nèi)存區(qū)域可以稱為一個進(jìn)程,內(nèi)存區(qū)域中是需要執(zhí)行代碼的,具體執(zhí)行代碼就是線程去執(zhí)行的。 需要注意的是:進(jìn)程只是負(fù)責(zé)開辟內(nèi)存空間的,線程才是負(fù)責(zé)執(zhí)行代碼邏輯的執(zhí)行單元。
除了線程和進(jìn)程外,我們更需要了解什么是管程,協(xié)程和纖程:
1.管程(Monitors):提供了一種機制,線程可以臨時放棄互斥訪問,等待某些條件得到滿足后,重新獲得執(zhí)行權(quán)恢復(fù)它的互斥訪問。
2.纖程(Fiber):是Microsoft組織為了幫助企業(yè)程序的更好移植到Windows系統(tǒng),而在操做系統(tǒng)中增加的一個概念,由操作系統(tǒng)內(nèi)核根據(jù)對應(yīng)的調(diào)度算法進(jìn)行控制,也是一種輕量級的線程。
3.協(xié)程(Coroutines):一種基于線程之上,但又比線程更加輕量級的存在,這種由程序管理的輕量級線程也被稱為用戶空間線程,對于內(nèi)核而言是不可見的。正如同進(jìn)程中存在多條線程一樣,線程中也可以存在多個協(xié)程。協(xié)程在運行時也有自己的寄存器、上下文和棧,協(xié)程的調(diào)度完全由用戶控制,協(xié)程調(diào)度切換時,會將寄存器上下文和棧保存到分配的私有內(nèi)存區(qū)域中,在切回來的時候,恢復(fù)先前保存的寄存器上下文和棧,直接操作棧則基本沒有內(nèi)核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非???。
[特別關(guān)注]:
1.纖程和協(xié)程的概念一致,都是線程的多對一模型,但有些地方會區(qū)分開來,但從協(xié)程的本質(zhì)概念上來談:纖程、綠色線程、微線程這些概念都屬于協(xié)程的范圍。
2.纖程和協(xié)程的區(qū)別在于:纖程是OS級別的實現(xiàn),而協(xié)程是語言級別的實現(xiàn),纖程被OS內(nèi)核控制,協(xié)程對于內(nèi)核而言不可見。
更多關(guān)于“java培訓(xùn)”的問題,歡迎咨詢千鋒教育在線名師。千鋒教育多年辦學(xué),課程大綱緊跟企業(yè)需求,更科學(xué)更嚴(yán)謹(jǐn),每年培養(yǎng)泛IT人才近2萬人。不論你是零基礎(chǔ)還是想提升,都可以找到適合的班型,千鋒教育隨時歡迎你來試聽。