情景:扣库存,会出现超扣的情况,因为同一个单子会有不同的工作人员使用,要保证数据的一致性。那么就用锁。
-
优化锁对象管理
使用 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}");
}
}
}