學習資料來自http://ifeve.com/java-concurrency-thread-directory/java
1、多線程數據庫
多線程在同一個程序內部併發執行,所以會對相同的內存空間進行併發讀寫操做。編程
思考: 服務器
2、多線程的優勢數據結構
1、資源利用率更好多線程
好比CPU在等待磁盤讀取的時間很是空閒,能夠利用這一段時間去作一些其餘的事情。併發
2、程序設計在某些狀況下更簡單負載均衡
好比單線程去操做兩個文件的讀取和處理,須要記錄每一個文件的讀取和處理狀態。相反,若是用兩個線程分別處理一個文件,一個線程在讀取的時候就會阻塞另外一個線程,此時,被阻塞的線程就能夠去執行處理的操做。不但提高磁盤和CPU利用率,編程也更加容易實現。異步
3、程序響應更快分佈式
例如服務器在某一個端口監聽進來的請求,當一個請求到來時它去處理這個請求,處理完了再返回去監聽其餘請求。假設這個請求須要佔用大量的時間呢?
另外一種方式是服務器監聽線程把進來的請求傳遞給工做者線程,而後立刻返回去監聽,這樣就可以接受和處理更多客戶端發送過來的請求,服務的響應也更快了。
3、多線程的代價
1、設計更復雜
通常來講,多線程應用程序比單線程應用程序更加複雜,在多線程訪問共享數據的時候,線程之間的交互每每很是複雜,不正確的線程同步產生的錯誤很是難以被發現,而且重現以修復。
2、上下文切換的開銷
當CPU執行一個線程切換到執行另一個線程的時候,它須要先存儲當前線程的本地數據、程序指針等,而後載入另外一個線程的本地數據、程序指針等,最後纔開始執行。這種切換叫作上下文切換(context switch),CPU會在一個上下文(context)中執行一個線程,而後切換到另外一個上下文(context)執行另一個線程。
若是沒有必要應該儘可能減小上下文的切換。
3、增長資源消耗
除了CPU,線程還須要一些內存來維持它本地的堆棧,也須要佔用操做系統中一些資源來管理線程。咱們能夠寫一個程序建立100個線程,而後這些線程只是等待什麼都不作,而後看看佔用了多少內存。
4、併發編程模型
併發編程模型指定了系統中的多線程如何經過協做來完成分配給它們的做業,不一樣的併發模型採用不一樣的方式拆分做業,同時線程間的協做和交互方式也不相同。
一、 併發模型與分佈式系統之間的類似性
併發模理相似於分佈式系統中使用的不少體系結構,在分佈式系統中進程之間能夠
通訊(進程可能在不一樣的機器中),在併發系統中線程之間也能夠相互通訊。例如爲工做者們(線程)分配做業的模型通常與分佈式系統中的負載均衡系統比較類似。
二、 並行工做者
委託者將傳入的做業被分配給不一樣的工做者上,每一個工做者完成整個任務,工做者們運做在不一樣的線程上,甚至可能在不一樣的CPU上。
優勢:容易理解,只須要添加更多的工做者來提升系統的並行度。
缺點:
等待訪問共享數據時,線程之間的互相等待會丟失部分並行性,許多併發數據結構是阻塞的,意味着在某個時刻只有一個或者不多的線程能訪問,致使共享數據出現競爭狀態,出現必定串行化。
三、 流水線模型
也叫反應器系統、事件驅動系統或者無共享模型。
相似於工廠生產線上的工人們,每一個工做者只負責做業中的部分工做,當完成了本身這部分工做就轉發給下一個工做者,每一個工做者在本身的線程中運行,並不會和其餘工做者共享狀態。
在實際中可能會有多個不一樣的虛擬流水線同時動做,現實多是這樣的狀況。
Actors和Channels
Actors模型中每一個工做者都被稱爲actor。Actor之間能夠直接異步地發送和處理消息,actor能夠用來實現一個或多個前面描述的那種做業處理流水線。
Channel模型中,工做都之間不直接進行通訊。相返,它們在不一樣的通道中發佈本身的消息(事件)。其餘工做者能夠在這些通道上監聽消息,發送者無需知道誰在監聽。
流水線模型的優勢:
流水線模型的缺點:
四、 函數式執行(Functional Parallelism)
函數式並行的基本思想是採用函數調用實現程序,函數被看做是代理人(agents)或者actor, 函數之間能夠像流水線模型(AKA反應器或者事件驅動系統)那樣互相發送消息。
思考:使用哪一種併發模型好呢?
一般狀況下,這個答案取決於你的系統打算作什麼。若是你的做業自己就是並行的、獨立的而且沒有必要共享狀態,你可能會使用並行工做者模型去實現你的系統。
不少做業都不是天然並行和獨立的,對於這種類型的系統,使用流水線併發模型可以更好的發揮它的優點,並且比並行工做者模型更有優點。