以 C# 为例,通常 lock 语句是被转化为对一个资源的无限长时间的等待,所以一旦资源被占用而又永不释放,那么必然死锁。
解决办法:
/// <summary>
/// 会自动释放的锁,可设置等待超时
/// </summary>
public class Lock : IDisposable
{
/// <summary>
/// 默认超时设置
/// </summary>
public static int DefaultMillisecondsTimeout = 15000; // 15S
private object _obj;
/// <summary>
/// 构造
/// </summary>
/// <param name="obj">想要锁住的对象</param>
public Lock(object obj)
{
TryGet(obj, DefaultMillisecondsTimeout, true);
}
/// <summary>
/// 构造
/// </summary>
/// <param name="obj">想要锁住的对象</param>
/// <param name="millisecondsTimeout">超时设置</param>
public Lock(object obj, int millisecondsTimeout)
{
TryGet(obj, millisecondsTimeout, true);
}
/// <summary>
/// 构造
/// </summary>
/// <param name="obj">想要锁住的对象</param>
/// <param name="millisecondsTimeout">超时设置</param>
/// <param name="throwTimeoutException">是否抛出超时异常</param>
public Lock(object obj, int millisecondsTimeout, bool throwTimeoutException)
{
TryGet(obj, millisecondsTimeout, throwTimeoutException);
}
private void TryGet(object obj, int millisecondsTimeout, bool throwTimeoutException)
{
if (Monitor.TryEnter(obj, millisecondsTimeout))
{
_obj = obj;
}
else
{
if (throwTimeoutException)
{
throw new TimeoutException();
}
}
}
/// <summary>
/// 销毁,并释放锁
/// </summary>
public void Dispose()
{
if (_obj != null)
{
Monitor.Exit(_obj);
}
}
/// <summary>
/// 获取在获取锁时是否发生等待超时
/// </summary>
public bool IsTimeout
{
get
{
return _obj == null;
}
}
}
object obj = new object();
using (Lock l = new Lock(obj, 10000))
{
//
}