情景:扣库存,会出现超扣的情况,因为同一个单子会有不同的工作人员使用,要保证数据的一致性。那么就用锁。
-
优化锁对象管理
使用 Lazy 初始化锁对象:
使用 ConcurrentDictionary 的 GetOrAdd 方法结合 Lazy 确保锁对象只被创建一次,避免多次创建。 -
减少锁的持有时间:避免长时间阻塞其他线程
思路:尽量减少在 lock 代码块内的操作,只将必须同步的代码放在其中。 -
处理异常情况
思路:对于异常情况,确保锁的正确释放,避免死锁或其他并发问题。
using System;
using System.Collections.Concurrent;
using System.Threading;class InventoryManager
{private static ConcurrentDictionary<string, Lazy<object>> lockObjects = new ConcurrentDictionary<string, Lazy<object>>();public static void ProcessOrder(int orderId, string material, string batch){string key = $"{material}:{batch}";Lazy<object> lockObject = lockObjects.GetOrAdd(key, new Lazy<object>(() => new object()));object actualLock = lockObject.Value;try{int productId = 0;int quantity = 0;// 先获取订单信息,不使用锁// 模拟从销售订单表获取订单信息// 提取产品 ID 和数量lock (actualLock){// 处理订单逻辑,包括销售订单、库存表、虚拟库存表的操作Console.WriteLine($"Processing order {orderId} for material {material} and batch {batch}");// 模拟从销售订单表获取订单信息// 模拟从库存表扣减库存// 模拟更新虚拟库存表Thread.Sleep(1000); }}catch (Exception ex){Console.WriteLine($"Error processing order: {ex.Message}");}}
}