併發編程的挑戰

一、多線程不一定快

當併發執行累加操作不超過百萬次時,速度會比串行執行累加操作慢。這是因爲線程有創建和上下文切換的開銷。

減少上下文切換的方法:

1.無鎖併發編程:多線程競爭鎖時,會引起上下文切換,所以多線程處理數據時,可以用一些辦法來避免使用鎖,如將數據的ID按照Hash算法取模分段,不同的線程處理不同段的數據。

2.CAS算法:Java的Atomic包使用CAS算法來更新數據,而不需要加鎖。

3.使用最少線程:避免創建不需要的線程,比如任務很少,但是創建了很多線程來處理,這樣會造成大量線程都處於等待狀態。

4.協程:在單線程裏實現多任務的調度,並在單線程裏維持多個任務間的切換。

 

二、避免死鎖的幾個常見方法

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

2.避免一個線程在鎖內同時佔用多個資源,儘量保證每個鎖只佔用一個資源。

3.嘗試使用定時鎖,使用lock.tryLock(timeout)來替代使用內部鎖機制。

4.對於數據庫鎖,加鎖和解鎖必須在一個數據庫連接裏,否則會出現解鎖失敗的情況。

 

三、資源限制的挑戰

(1)什麼是資源限制

資源限制是指在進行併發編程時,程序的執行速度受限於計算機硬件資源或軟件資源。

(2)資源限制引發的問題

在併發編程中,將代碼執行速度加快的原則是將代碼中串行執行的部分變成併發執行,

但是如果將某段串行的代碼併發執行,因爲受限於資源,仍然在串行執行,這時候程序不僅不會加快執行,反而會更慢,因爲增加了上下文切換和資源調度的時間。

(3)如何解決資源限制的問題

對於硬件資源限制,可以考慮使用集羣並行執行程序。既然單機的資源有限制,那麼就讓程序在多機上運行。比如使用ODPS、Hadoop或者自己搭建服務器集羣,不同的機器處理不同的數據。可以通過“數據ID%機器數”,計算得到一個機器編號,然後由對應編號的機器處理這筆數據。對於軟件資源限制,可以考慮使用資源池將資源複用。比如使用連接池將數據庫和Socket連接複用,或者在調用對方webservice接口獲取數據時,只建立一個連接。

(4)在資源限制情況下進行併發編程

如何在資源限制的情況下,讓程序執行得更快呢?方法就是,根據不同的資源限制調整

程序的併發度,比如下載文件程序依賴於兩個資源——帶寬和硬盤讀寫速度。有數據庫操作

時,涉及數據庫連接數,如果SQL語句執行非常快,而線程的數量比數據庫連接數大很多,則某些線程會被阻塞,等待數據庫連接。

 

                                                                                                    摘抄自《Java併發編程的藝術》方騰飛  魏鵬 程曉明 著

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章