併發編程學習(1)----併發編程基礎

前言:多線程是程序員必須掌握的一項基礎知識,可是因爲各類框架封裝使得咱們平時不多能接觸到多線程。一旦項目中發生問題,便無從下手。學會了多線程不只能幫助你更好地處理項目中的問題,還能對你理解一些框架有所幫助。本系列以《Java併發編程的藝術》爲參考,結合網上的一些資料並結合本身的理解整理而成。若有錯誤,歡迎指正。 程序員

一、幾個概念算法

1)進程:是具備必定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的獨立單位。一個操做系統中能夠同時運行多個任務(程序),每一個運行的任務(程序)被稱爲一個進程。例如,啓動一個Java程序,操做系統就會建立一個Java進程。數據庫

2)線程:它是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。線程本身基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),可是它能夠與其它同屬一個進程的其餘線程共享進程所擁有的所有資源。編程

3)上線文切換:服務器

  即便單核處理器也支持多線程執行代碼,CPU經過給每一個線程分配CPU時間片來實現這個機制。時間片是CPU分配給各個線程的時間,由於時間片很是短,因此CPU經過不停地切換線程執行,讓咱們感受多個線程是同時執行的。多線程

  CPU經過時間片分配算法來循環執行任務,當前任務執行一個時間片後會切換到下一個任務。可是,在切換前會保存上一個任務的狀態,以便下次切換回這個任務時,能夠再加載這個任務的狀態。因此任務從保存到再加載的過程就是一次上下文切換。併發

  這就比如咱們同時讀兩本書,當在讀一本英文的技術書時,發現某個單詞不認識,因而便打開字典查找,可是查找以前必須先記住這本書已經讀到了多少頁的多少行。等查完單詞之後,可以繼續讀這本書。這樣的切換是會影響讀書效率的,一樣上下文切換也會影響多線程的執行效率。框架

2.爲何要使用多線程?工具

1)充分利用系統資源性能

  因爲摩爾定律週期愈來愈長,處理器性能的提高方式也從更高的主頻向多核發展。線程是大多數操做系統調度的基本單元,而線程是進程的一個實體。一個線程同一時刻只能運行在一個cpu上,這樣就沒法充分利用系統資源。若是將計算任務分配給多個處理器核上,就會顯著減小程序的處理時間。

2)更快地響應時間

  例如,在一些複雜的業務中,用戶從點擊按鈕開始,服務端須要進行一系列處理過程才能將最終的結果返回給客戶端。使用多線程技術,能夠將實時性要求高的數據處理完成之後即將執行結果返回到客戶端。而一些數據一致性不強的操做派發給其它線程處理(如消息隊列/Worker)。這樣能夠縮短響應時間,提高了用戶體驗。

3)更好的編程模型

  Java爲多線程提供了良好的、考究而且一致的編程模型,使得開發人員更加專一於問題的解決。某些類型的問題,例如仿真,沒有併發是很難解決的。大多數人都看到過至少一種形式的仿真,例如計算機遊戲中或電影中計算機生成的動畫。完整的仿真一般涉及許多交互式元素,每個都有本身的「想法」。從編程角度看,模擬每一個仿真元素都是獨立的任務----好比遊戲中的門與岩石,或者精靈與巫師。(詳細可參考Tink in Java第四版 21.1.2小節)

3.多線程面臨的問題

  在併發編程中,須要解決的兩個問題:線程之間如何通訊以及線程之間如何同步。通訊是指線程之間以何種機制來交換信息,同步是指程序中用於控制不一樣線程間相對執行順序的機制。

1)線程間的通訊機制有兩種:共享內存和消息傳遞。

  共享內存的併發模型中,線程之間共享程序的公共狀態,經過寫-讀內存中的公共狀態進行隱式通訊。在消息傳遞的併發模型裏,線程之間沒有公共狀態,線程間的通訊必須經過發送消息來進行顯示通訊(好比Java中Object對象的wait()與notify())。

2)同步機制

  在併發編程中,尤爲是在處理共享資源時,須要將某些操做(例如寫操做)轉化爲同步,以避免形成不可思議的後果。常見的同步機制有如下兩種:JVM層面,藉助Object的monitor實現(synchronized);經過總線鎖或者鎖定內存部分區域實現,例如volatile。

四、併發編程挑戰

1)上下文切換。

  當線程較多時,頻繁的上線文切換會致使執行效率下降,合理地調整線程數能夠將併發執行效率最大化。

2)死鎖。

  鎖是很是有用的工具,運用場景很是多。可是若是使用不當可能會帶來死鎖問題,嚴重時可能使系統癱瘓。死鎖即建立兩個線程A和B,A擁有鎖a,同時須要獲取鎖b,而B擁有鎖b,同時須要獲取鎖a。二者均持有鎖,沒法獲取所需鎖。在實際開發中,要避免死鎖的產生。

  避免死鎖的常見方法

  a.避免一個線程同時獲取多個鎖

  b.便面一個線程在鎖內同時佔用多個資源,儘可能保證每一個鎖只佔用一個資源。

  c.嘗試使用定時鎖,使用lock.tryLock(timeout)

       d.對程序進行異常處理,保證程序發生異常時鎖能夠正常釋放。

       d.對於數據庫鎖,加鎖和解鎖必須在同一個數據庫鏈接裏,不然會出現解鎖失敗問題。

3)資源限制。

  資源限制指在併發編程中,受限於計算機硬件資源或軟件資源。例如,一個服務器的貸款只有2M/s,當使用多線程時,並不會提升下載速度。由於受限於資源,線程仍然是串行執行。程序反而會更慢,因爲上下文切換和資源調度時間。

  對於硬件資源,能夠經過增長帶寬或者增長集羣方式解決。對於軟件資源,例如數據庫鏈接,能夠經過控制線程併發數來使得資源利用率最大化。

相關文章
相關標籤/搜索