參考文章:https://www.cnblogs.com/dingfangbo/p/5769501.htmlhtml
1、lock 確保只有一個線程訪問某個資源或某段代碼。通俗的講就是多個線程操做相同的鎖對象,只能一個線程操做完畢,例外的線程才能繼續訪問鎖定資源代碼併發
以下代碼:spa
1.修改鎖定對象 的屬性線程
RYAreaEmpPathWayVM areaEmpPathWayVM = instance.systemConfigDistributor.GetAreaEmpPathWayDetail(epcVM.TenantLayerCode, epcVM.epc_no); if (areaEmpPathWayVM != null) { //因爲區域僱員運動軌跡對象是動態對象故而鎖定對象 lock (areaEmpPathWayVM) { //業務邏輯1: #region 一、更新屬性:最近刷卡4G設備號、最近進入區域的時間 areaEmpPathWayVM.recent_device4g_no = epcVM.ry_device4g_no; areaEmpPathWayVM.recent_probe_time = epcVM.create_time; #endregion //業務邏輯2 #region .更新屬性:第一次進入區域時間、最近刷卡4G設備號、最近進入區域的時間、最近進入區域ID、上一次被刷卡讀頭地址、最近刷卡讀頭地址 areaEmpPathWayVM.first_In_time = epcVM.create_time; areaEmpPathWayVM.last_in_area_id = last_uhfPath.area_id; areaEmpPathWayVM.last_probe_time = ALUtils.CloneObj<DateTime>(areaEmpPathWayVM.recent_probe_time); ////////////////////////////////////////////////////////////////////////////////// areaEmpPathWayVM.recent_device4g_no = epcVM.ry_device4g_no; areaEmpPathWayVM.recent_probe_time = epcVM.create_time; areaEmpPathWayVM.recent_in_area_id = epcVM.access_Area_ID; areaEmpPathWayVM.recent_uhf_portaddress = epcVM.uhf_portaddress; #endregion } }
2.讀取鎖定對象的屬性進行邏輯判斷code
RYAreaEmpPathWayVM tempRYAreaEmpPathWayVM = instance.systemConfigDistributor.GetAreaEmpPathWayDetail(alarmGenerateVM.org_layer_code, alarmGenerateVM.epc_no); if (tempRYAreaEmpPathWayVM != null) { lock (tempRYAreaEmpPathWayVM) { if (!tempRYAreaEmpPathWayVM.recent_probe_time.HasValue || !tempRYAreaEmpPathWayVM.first_In_time.HasValue) return false; //若是最新讀頭第一次進入區域的時間與告警參數中第一次進入區域時間不相同,則僱員發生折返,不處理,不然處理 if (tempRYAreaEmpPathWayVM.first_In_time != alarmGenerateVM.create_time) return false; return true; } }
2、鎖定的資源若是已經刪除,須要二次判斷對象資源是否存在htm
以下代碼:對象
1.刪除併發集合某個鍵值blog
ConcurrentDictionary<string, RyAreaInEmpVM> temp = instance.GetAreaInEmpMap(vm.org_layer_code, vm.area_id); if (temp != null) { RyAreaInEmpVM aieDeleteVM; temp.TryRemove(vm.ID, out aieDeleteVM); }
2.若是多個線程訪問已經鎖定的資源會造成阻塞隊列,這樣當某個線程釋放鎖資源,還能夠繼續訪問代碼,可是實際已經被刪除(鍵值),隊列
因此二次加鎖判斷。資源
//查詢條件:租戶ID、區域ID、僱員ID 沒有區域在場人員數據,則不執行 var aieVM = instance.areaController.GetAreaInEmpDetailByEmpId(ryAreaExitEmpVM.org_layer_code, ryAreaExitEmpVM.area_id, ryAreaExitEmpVM.emp_id); if (aieVM != null) { lock (aieVM) { aieVM = instance.areaController.GetAreaInEmpDetailByEmpId(ryAreaExitEmpVM.org_layer_code, ryAreaExitEmpVM.area_id, ryAreaExitEmpVM.emp_id); if (aieVM != null) { lock (aieVM) { #region 1.區域告警消除 ....... #endregion #region 2.1 刪除離開區域僱員 ....... #endregion } } } }