using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace FZJ.Lock { /// <summary> /// 等值锁定 /// 锁定给定内容 /// 内容必须实现IComparable接口,若Comparable比较两个对象是同一个值, /// 则在相等对象上执行的操作是同步的 /// 实际上未对给定对象进行锁定,在外部可以调用lock等 /// </summary> public class EquivalentLock<T> where T : IComparable<T> { Dictionary<T, Semaphore> t2Event = new Dictionary<T, Semaphore>(); System.Threading.SpinLock sl = new SpinLock(); /// <summary> /// 进入锁定内容 /// </summary> /// <param name="lockObj">被锁定的内容</param> public void Enter(T lockObj) { bool lockTaken = false; sl.Enter(ref lockTaken); if (!t2Event.ContainsKey(lockObj)) { t2Event.Add(lockObj, new Semaphore(1, 1)); } sl.Exit(); t2Event[lockObj].WaitOne(); } /// <summary> /// 退出锁定内容 /// </summary> /// <param name="lockObj">锁定的内容</param> public void Exit(T lockObj) { if (!t2Event.ContainsKey(lockObj)) { throw new KeyNotFoundException(); } t2Event[lockObj].Release(); } /// <summary> /// 释放存储资源 /// </summary> public void Free() { t2Event.Clear(); } } }
方法调用方式。
class Program { static void Main(string[] args) { EquivalentLock<string> stringLock = new EquivalentLock<string>(); for (int i = 0; i < 10; i++) { new Thread(() => { string ss = new string('1', 3); int threadHashCode = System.Threading.Thread.CurrentThread.GetHashCode(); Console.WriteLine(threadHashCode + "尝试进来"); stringLock.Enter(ss); //do something Console.WriteLine(threadHashCode + "进来"); Thread.Sleep(1000); Console.WriteLine(threadHashCode + "出来"); stringLock.Exit(ss); }).Start(); } Console.WriteLine("是否释放资源?(y/n)"); string isFree = Console.ReadLine(); if (isFree == "y") { stringLock.Free(); } Console.Read(); } }
本文深入探讨了等值锁定机制的实现原理,该机制通过使用Semaphore和SpinLock确保相同值的对象在多线程环境下同步操作,避免竞态条件。文章提供了具体的C#代码示例,展示了如何创建和使用EquivalentLock类来管理线程间的资源访问。
1482

被折叠的 条评论
为什么被折叠?



