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(); } }
时间: 2024-12-25 10:58:05