网站ip pv值,瑞安网站制作,网站横幅怎么制作教程,网页设计师培训费用我们知道通过lock一个固定静态object给代码段加同步锁#xff0c;可以让多个线程的同时调用以同步执行#xff0c;因此可以利用字典来给不同参数分配不同的静态对象#xff0c;方法中不同的参数调用锁住各自不同的静态对象即可实现不同参数不加锁#xff0c;相同参数才加锁…
我们知道通过lock一个固定静态object给代码段加同步锁可以让多个线程的同时调用以同步执行因此可以利用字典来给不同参数分配不同的静态对象方法中不同的参数调用锁住各自不同的静态对象即可实现不同参数不加锁相同参数才加锁的需求而多线程更新操作的字典需要用到线程安全的ConcurrentDictionary防止争用因此这里的静态加锁对象字典类型为ConcurrentDictionarystring, object。
比如场景在数据库某表没有唯一约束的情况下有可能前端请求和程序定时服务同时执行写入操作这时写入操作在不同的线程中执行虽然写入之前作了判断记录是否已存在的操作但可能两个线程同时执行都判断了记录不存在因此都执行了写入操作就造成了记录重复的可能。
写一个调用管理类“MultiInvokeManager”通过该类来控制这种相同参数同时调用的可能性
/// summary
/// 多线程调用方法控制类
/// /summary
public static class MultiInvokeManager
{//参数调用匹配加锁对象字典private static readonly ConcurrentDictionarystring, object _lockMap new ConcurrentDictionarystring, object(); /// summary/// 根据调用参数比如方法参数中唯一的订单号对应的“key”排除相同参数的“action”操作同时被执行/// /summary/// param namekey相同参数匹配相同的key(比如唯一的订单号)以便相同参数不可同时调用/param/// param nameaction通过key是否相同决定是否需要限制同步执行的操作/parampublic static void SyncInvokeForSameArgs(string key, Action action){object obj _lockMap.GetOrAdd(key, new object());lock (obj){action();}}/// summary/// 控制的操作执行后在适当的时机调用该方法释放字典中的对象以便垃圾回收防止累积占用内存/// /summary/// param namekey/parampublic static void ReleaseLockObject(string key){_lockMap.TryRemove(key, out _);}
}
1. 程序定时服务中调用
MultiInvokeManager.SyncInvokeForSameArgs(tradeNo, () UpdateUserMemberStatus(userId, tradeNo, transactionId, payAmount).Wait()
);
MultiInvokeManager.ReleaseLockObject(tradeNo);
2. 前端请求方法中调用
MultiInvokeManager.SyncInvokeForSameArgs(tradeNo, () UpdateMemberStatus(tradeNo, transactionId, payAmount).Wait()
);
MultiInvokeManager.ReleaseLockObject(tradeNo); 以上两处调用中“UpdateUserMemberStatus”和“UpdateMemberStatus”方法执行的都是判断“tradeNo”在原来某历史表中是否已经存在不存在则Insert历史表并Update关联主表的相同操作因此利用上面管理类“MultiInvokeManager”来控制防止相同参数的写入可能同时发生的可能同时保持不同参数的写入依旧可以在不同线程中同时进行