在參照一些行業系統軟體的時候,發現一個做的挺不錯的系統功能-系統參數管理,相當於把任何一個基礎的系統參數碎片化進行管理,每次可以讀取一個值進行管理,這樣有利於我們快速的處理業務需求,是一個挺好的功能。本篇隨筆模擬這個功能,基於SqlSugar開發框架的基礎上,利用代碼生成工具快速生成系統參數管理界面... ...
開發中經常遇到不同的業務訪問同一個數據源,而每一個業務的執行流就是一個線程,此時線程一多就會產生多線程最容易遇到的問題——併發。
什麼是併發?
舉個很經典的例子:程式中我們經常要操作一些對象,尤其是記憶體中的數據
例如當前判斷進入條件已經判斷newModel不為空,sleep(10)稱為比較耗時的運算,在此期間如果別的地方把newModel置空,等到sleep(10)結束就會產生異常,這裡sleep只是一個放大的時間,實際業務中這種運算絕大部分都是毫秒甚至微妙級別的,不進行代碼review很難發現這方面的問題,從而導致項目產生各種莫名其妙異常。
怎麼解決併發?
關於併發解決網上這方面教程也比較多,主要為加鎖,設計模式-單例模式這兩種結合解決併發問題。這裡就暫時不詳細舉例了。記憶體中的集合數據可能比較常見的保存方式就是list,array,queue等,但是這些都是線程非安全的,在多線程操作中需要手動加鎖,代碼龐大之後,就有概率在一些地方丟鎖或者重覆加鎖,更嚴重甚至產生死鎖。
既然有線程非安全,那必然有線程安全,線程安全集合有主要有五種(ConcurrentQueue,ConcurrentStack,ConcurrentBag,BlockingCollection,ConcurrentDictionary),他們在一定程度上使用了無鎖技術和記憶體屏障比正常使用互斥鎖有一定性能提升。這裡說明一下BlockingCollection。
BlockingCollection類似阻塞隊列,其最舒服的地方位於它是實現了生產者——消費者的關係,比ConcurrentQueue好太多,同時他還支持foreach與限制最大容量。
BlockingCollection.Add 如果生產超過指定容量BlockingCollection會自身阻塞停止生產
BlockingCollection.Take如果消費過多,沒有生產的內容,則會自身阻塞直到有新的生產內容加入,避免取空現象節約性能。