在开发中为了防止多个线程同时访问同一资源的时候 ,我们一般会进行加锁处理,但看到有些同事写的那些散落的加锁代码感觉有些不太美观,于是自己给封装下:
无标题
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 = null, bool 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 != null) Monitor.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);
}
}