封装一个锁处理类

在开发中为了防止多个线程同时访问同一资源的时候 ,我们一般会进行加锁处理,但看到有些同事写的那些散落的加锁代码感觉有些不太美观,于是自己给封装下:

无标题


internal struct TimedLock : IDisposable
{
        /// <summary>
        /// 默认超时秒数
        /// </summary>
        private const int timeoutSeconds = 5;
        /// <summary>
        /// 锁住对象
        /// </summary>
        private object target;
        /// <summary>
        /// 超时抛出异常
        /// </summary>
        private static bool throwTimeoutException;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="o"></param>
        private TimedLock(object o)
        {
            target = o;
        }
        /// <summary>
        /// 锁住对象
        /// </summary>
        /// <param name="o">想要锁住的对象</param>
        /// <param name="timeout">超时设置,默认为int.MaxValue</param>
        /// <param name="throwException">超时抛出异常</param>
        /// <returns></returns>
        public static TimedLock Lock(object o, TimeSpan? timeout = nullbool throwException = false)
        {
            if (timeout == null)
            {
                timeout = TimeSpan.FromSeconds(timeoutSeconds);
            }
            throwTimeoutException = throwException;
            return GetLock(o, timeout.Value);
        }
        /// <summary>
        /// 获取锁
        /// </summary>
        /// <param name="o">想要锁住的对象</param>
        /// <param name="timeout">超时设置</param>
        /// <returns></returns>
        private static TimedLock GetLock(object o, TimeSpan timeout)
        {
            TimedLock tl = new TimedLock(o);
            if (!Monitor.TryEnter(o, timeout) && throwTimeoutException)
            {
                   throw new TimeoutException("Timeout waiting for lock");
            }
            Console.WriteLine("Entered Thread " + Thread.CurrentThread.GetHashCode() + ":" + DateTime.Now);
            return tl;
        }
        /// <summary>
        /// 销毁,并释放锁
        /// </summary>
        public void Dispose()
        {
            if (target != nullMonitor.Exit(target);
        }
        
}
 
调用示例:
class Program
    {
        private static object o = new object();
        static void Main(string[] args)
        {
            //Retry();
            var t1 = new Thread(new ThreadStart(LockedSample1));
            t1.Name = "t1";
            t1.Start();
            var t2 = new Thread(new ThreadStart(LockedSample1));
            t2.Name = "t2";
            t2.Start();

            Console.ReadKey();
        }

        static void LockedSample1()
        {
            using (TimedLock lo = TimedLock.Lock(o, TimeSpan.FromSeconds(5), true))
            {
                LockedSample2();
            }
        }

        static void LockedSample2()
        {
            System.Threading.Thread.Sleep(10000);
        }
}
 
 
    
posted @ 2017-09-30 15:54  tqyitweb  阅读(316)  评论(0编辑  收藏  举报