這個寫出來,純屬自娛自樂,以後還得再改正。
什麼是并發程式設計?
并發程式設計目的是為了讓程式運作的更快(也不是線程越多,越快,這裡會遇到很多的問題,不如上下文切換問題,死鎖的問題,以及受限于硬體和軟體的資源限制)
上下文切換(任務從儲存到再加載的過程)(類似于我們玩的單機遊戲的存檔,可以不同的人來玩一樣)
什麼是上下文切換?
是指CPU從一個程序或者線程切換到另一個程序或者線程
剩下文切換的步驟?
1 挂起一個程序或者線程,将這個線程在cpu中的狀态(對,沒錯這個狀态就叫做上下文)存儲在記憶體中的某處 2 線上程中檢索寫一個線程的上下文并在CPU寄存器中恢複 3跳轉到上一個線程被中斷的代碼行(我想這也就是需要程式計數器和寄存器的原因,抱歉寄存器我現在都還沒搞懂)
即使是單核CPU也是支援多線程執行代碼的,CPU通過給每個線程配置設定CPU時間片(CPU配置設定給各個線程的時間)來實作這個機制,因為時間片非常短,是以CPU通過不停的切換線程線程執行,讓我們感覺多個線程是同時執行的,時間片一般是幾十毫秒。
CPU通過時間片配置設定算法來循環執行任務,目前任務執行一個時間片後會切換到下一個任務。但是,在切換前會儲存上一個任務的狀态,以便下次切換會這個任務,可以再加載這個任務的狀态,是以任務從儲存到再加載的過程就是一次上下文切換。
上下文的切換是會影響效率(任務的執行時間)的,同樣上下文切換也會影響多線程的執行速度。
減少上下文切換實戰

類似于上面的這個例子serial()方法是單線程的執行時間測試concurrency()是多線程的時間效率的測試。
那麼當操作不超過百萬次時,并發會比串行的執行速度要慢,為什麼會産生這種情況,因為線程有建立和上下文切換的開銷。
那我們就來測試一下上下文切換的次數和時間的長短 具體來看看
從cs可以看出上下文切換,每隔一秒就要切換1000多次。也就是切換一次需要1ms喽,也就是說當我們執行一段程式時,上下文在不停的切換,增加了我們的執行書時間。
如何減少上下文的切換
具體有(無鎖并發程式設計,CAS算法,使用最少線程和使用協程)
無鎖并發程式設計:多線程競争鎖時,會引起上下文切換,是以多線程處理資料時,可以用一些辦法來避免使用鎖,如将資料的ID按照HaSh算法取模分段,不同的線程處理不同段的資料(這裡我不太清楚他指的資料是什麼資料?一般for循環不都是每一一個資料嗎?(這裡應該指的是多核處理器執行吧))
CAS算法:java的Atomic包使用CAS算法來更新資料,而不需要加鎖。
使用最少線程:這個比較簡單,就是避免建立不需要的線程,比如任務很少,但是建立了很多線程來處理,這樣會造成大量的線程都處于等待狀态(我就想不通,難道處于等待狀态的線程也會浪費時間?想通了,當線程建立的時候是NEW狀态,然後建立完成之後就成了Runnable狀态,這個轉換是需要時間的,這裡的比如執行一個任務,我們有兩個線程A和B的話,那麼這個任務肯定就要不就是線程A執行 要不就是線程B執行,切換頻率肯定小,而且因為我們的處理器處理的線程是有限的,如果100個的話,那麼誰做還不确定,有空閑的線程,在等待回調消息之後有可能就直接切換别的線程進行執行了,是以上下文切換比較多)。
協程:在單線程裡實作多任務的排程,并在單線程裡維持多個任務間的切換(哇這什麼鬼,難道在繞密碼嗎,還是我太菜了 其實是當一個線程執行一個任務的時間片段到了之後,然後需要自己手動中斷,然後儲存上下文的狀态,然後讓這個線程再繼續執行下面的直到任務結束,相當于單任務的多線程單核執行吧 ,而且是和多線程一塊進行,互不影響)。
死鎖
鎖我們經常使用,但是它也會給我們帶來一些困擾,那就是可能會引起死鎖,一旦産生死鎖,就會造成系統功能不可用。
A等待B釋放 B等待A釋放 造成無限死循環 就會造成死鎖
當然顯示情況中我們并不會寫出這樣的代碼,但是在我們寫的過程中,比如線程A拿到了鎖,但是因為一些異常,沒有釋放這個鎖,或者說,線程A拿到了一個資料庫鎖,釋放鎖的時候抛出了異常,沒釋放掉,一旦出現死鎖,業務就得停止,那麼就隻能通過dump線程檢視到底是哪個線程出現了問題。
通過dump線程檢視到的結果,他會告訴你是哪個類的多少行引起了死鎖,對應我們上邊的就是,42和31
下面我們來介紹避免死鎖的幾個常見方法
避免一個線程同時擷取多個鎖
避免一個線程在鎖内同時占用多個資源,盡量保證每個鎖隻占用一個資源
闡釋使用定時鎖使用lock.tryLock(timeout)來替代使用内部鎖機制
對于資料庫加鎖,加鎖和解鎖必須在一個資料庫連接配接裡,否則會出現解鎖失敗的情況。
資源限制的挑戰
1什麼是資源限制
資源限制是指在進行并發程式設計時,程式的執行速度受限于計算機硬體資源或軟體資源,例如伺服器的帶寬隻有2MB/S,某個資源的下載下傳速度是1MB/S每秒,系統啟動10個線程下載下傳資源,下載下傳速度不會變成10Mb每秒,是以在進行并發程式設計時,要考慮這些資源的限制,硬體資源限制有帶寬的上傳/下載下傳速度,硬碟讀寫速度和CPU的處理速度,軟體資源限制有資料庫的連接配接和SOCKET連接配接數等等。
2資源限制引發的并發問題
在并發程式設計的過程中,将代碼執行加快的原則是将代碼中串行執行的部分程式設計并發程式設計
但是如果将某段串行的代碼并發執行,因為受限于資源仍然在串行執行,這時候程式不僅不會加快執行,反而會變更慢,因為增加了上下文切換和資源排程時間。
3如何解決資源限制問題
對于硬體資源的限制,我們可以考慮叢集并行程式,既然單機的資源有限制,那就在多機上進行運作。
對于軟體資源限制,可以考慮使用資源池将資源複用,比如使用連接配接池連接配接資料庫和socket連接配接複用,