更新時間:2021-03-19 15:15:07 來源:動力節點 瀏覽1965次
線程是進程中的一個獨立控制單元,線程在控制著進程的執行,一個進程中至少有一個線程。多線程可以更好地利用cpu的資源,線程之間還能進行數據共享。在IT中,一個線程是指進程中的一個執行流程,一個進程可以運行多個線程,IT中每個線程都有一個調用棧,即使不在程序中創建任何新的線程,也有一個main()方法運行在一個線程內,稱為主線程,一旦創建一個新的線程,就產生一個新的調用棧。通過該專題課程的系統學習,讓大家一次性搞明白IT中的多線程。
零基礎學習Java多線程與并發,推薦動力節點的Java多線程視頻教程,帶你一次搞明白Java多線程高并發
課程目標:通過本系列課程的學習,一次性搞明白多線程,提升自身技術能力與價值。
適用人群:具有IT基礎的人群,希望系統學習IT多線程的人群。
1.計算機系統
使用高速緩存來作為內存與處理器之間的緩沖,將運算需要用到的數據復制到緩存中,讓計算能快速進行;當運算結束后再從緩存同步回內存之中,這樣處理器就無需等待緩慢的內存讀寫了。
緩存一致性:多處理器系統中,因為共享同一主內存,當多個處理器的運算任務都設計到同一塊內存區域時,將可能導致各自的緩存數據不一致的情況,則同步回主內存時需要遵循一些協議。
亂序執行優化:為了使得處理器內部的運算單位能盡量被充分利用。
2.Java內存模型
目標是定義程序中各個變量的訪問規則。(包括實例字段、靜態字段和構成數組的元素,不包括局部變量和方法參數)
所有的變量都存儲在主內存中(虛擬機內存的一部分)。
每條線程都由自己的工作內存,線程的工作內存中保存了該線程使用到的變量的主內存副本拷貝,線程對變量的所有操作都必須在工作內存中進行,而不能直接讀寫主內存中的變量。
線程之間無法直接訪問對方的工作內存中的變量,線程間變量的傳遞均需要通過主內存來完成。
內存間交互操作:
Lock(鎖定):作用于主內存中的變量,把一個變量標識為一條線程獨占的狀態。
Read(讀取):作用于主內存中的變量,把一個變量的值從主內存傳輸到線程的工作內存中。
Load(加載):作用于工作內存中的變量,把read操作從主內存中得到的變量的值放入工作內存的變量副本中。
Use(使用):作用于工作內存中的變量,把工作內存中一個變量的值傳遞給執行引擎。
Assign(賦值):作用于工作內存中的變量,把一個從執行引擎接收到的值賦值給工作內存中的變量。
Store(存儲):作用于工作內存中的變量,把工作內存中的一個變量的值傳送到主內存中。
Write(寫入):作用于主內存中的變量,把store操作從工作內存中得到的變量的值放入主內存的變量中。
Unlock(解鎖):作用于主內存中的變量,把一個處于鎖定狀態的變量釋放出來,之后可被其它線程鎖定。
規則:
不允許read和load、store和write操作之一單獨出現。
不允許一個線程丟棄最近的assign操作,變量在工作內存中改變了之后必須把該變化同步回主內存中。
不允許一個線程沒有發生過任何assign操作把數據從線程的工作內存同步回主內存中。
一個新的變量只能在主內存中誕生。
一個變量在同一時刻只允許一條線程對其進行lock操作,但可以被同一條線程重復執行多次。
如果對一個變量執行lock操作,將會清空工作內存中此變量的值,在執行引擎使用這個變量前,需要重新執行read、load操作。
如果一個變量事先沒有被lock操作鎖定,則不允許對它執行unlock操作。
8.對一個變量執行unlock操作前,必須先把該變量同步回主內存中。
3.volatile型變量
保證此變量對所有線程的可見性。每條線程使用此類型變量前都需要先刷新,執行引擎看不到不一致的情況。
運算結果并不依賴變量的當前值、或者確保只有單一的線程修改變量的值。
變量不需要與其他的狀態變量共同參與不變約束。
禁止指令重排序優化。普通的變量僅保證在方法執行過程中所有依賴賦值結果的地方都能獲取到正確的結果。而不能保證賦值操作的順序與程序代碼中的順序一致。
load必須與use同時出現;assign和store必須同時出現。
4.原子性、可見性與有序性
原子性:基本數據類型的訪問讀寫是具備原子性的,synchronized塊之間的操作也具備原子性。
可見性:指當一個線程修改了共享變量的值,其他線程能夠立即得知這個修改。synchronized(規則8)和final可以保證可見性。Final修飾的字段在構造器中一旦被初始化完成,并且構造器沒有把this的引用傳遞出去,那么在其他線程中就能看見final字段的值。
有序性:volatile本身包含了禁止指令重排序的語義,而synchronized則是由規則5獲得的,這個規則決定了持有同一個所的兩個同步塊只能串行地進入。
5.先行發生原則
IT內存模型中定義的兩項操作之間的偏序關系,如果操作A先行發生于操作B,其實就是說在發生操作B之前,操作A產生的影響能被操作B觀察到。
程序次序規則:在一個線程內,按照代碼控制流順序,在前面的操作先行發生于后面的操作。
管程鎖定規則:一個unlock操作先行發生于后面對同一個鎖的lock操作。
Volatile變量規則:對一個volatile變量的寫操作先行發生于后面對這個變量的讀操作。
線程啟動規則:Thread對象的start()方法先行發生于此線程的每個操作。
線程終止規則:線程中的所有操作都先行發生于對此線程的終止檢測。
線程中斷規則:對線程的interrupt()方法的調用先行發生于被中斷線程的代碼檢測中斷事件的發生。
對象終結過則:一個對象的初始化完成先行發生于它的finalize()方法的開始。
傳遞性:如果操作A先行發生于操作B,操作B現象發生于操作C,那么就可以得出操作A先行發生于操作C的結論。
時間上的先后順序與先行發生原則之間基本上沒有太大的關系。
6.線程實現
使用內核線程實現:
內核線程Kernel Thread:直接由操作系統內核支持的線程,這種線程由內核類完成線程切換,內核通過操縱調度器對線程進行調度,并負責將線程的任務映射到各個處理器上。
輕量級進程Light Weight Process:每個輕量級進程都由一個內核線程支持。
局限性:各種進程操作都需要進行系統調用(系統調用代價相對較高,需要在用戶態和內核態中來回切換);輕量級進程要消耗一定的內核資源,一次一個系統支持輕量級進程的數量是有限的。
使用用戶線程實現:
用戶線程:完全建立在用戶空間的線程庫上,系統內核不能直接感知到線程存在的實現。用戶線程的建立、同步、銷毀和調度完全在用戶態中完成,不需要內核的幫助。所有的線程操作都需要用戶程序自己處理。
混合實現:
將內核線程和用戶線程一起使用的方式。操作系統提供支持的輕量級進程則作為用戶線程和內核線程之間的橋梁。
Sun JDK,它的Windows版和Linux版都是使用一對一的線程模型來實現的,一條IT線程映射到一條輕量級進程之中。
以上就是動力節點Java培訓機構的小編針對“Java多線程與并發視頻之學習總結”的內容進行的回答,希望對大家有所幫助,如有疑問,請在線咨詢,有專業老師隨時為你服務。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習