多线程写入日志读写锁

多线程写入日志

读写锁 ReaderWriterLock 、就是支持单个写线程和多个读线程的锁。自.NET 3.5 开始 ReaderWriterLockSlim登上舞台,ReaderWriterLockSlim 可以看做是 ReaderWriterLock 的升级版。 由于 ReaderWriterLockSlim 默认不支持递归调用、所以在某种意义上来说更不容易造成死锁。
ReaderWriterLockSlim 类支持三种锁定模式:Read,Write,UpgradeableRead。这三种模式对应的
方法分别是 EnterReadLock,EnterWriteLock,EnterUpgradeableReadLock 。再就是与此对应的 
TryEnterReadLock,TryEnterWriteLock,TryEnterUpgradeableReadLock,ExitReadLock,
ExitWriteLock,ExitUpgradeableReadLock。Read 和 Writer 锁定模式比较简单易懂:Read 模式是典
型的共享锁定模式,任意数量的线程都可以在该模式下同时获得锁;Writer 模式则是互斥模式,在该
模式下只允许一个线程进入该锁。UpgradeableRead 锁定模式可能对于大多数人来说比较新鲜,但是
在数据库领域却众所周知。

备注及注意事项

1、对于同一把锁、多个线程可同时进入读模式。
2、对于同一把锁、同时只允许一个线程进入写模式。
3、对于同一把锁、同时只允许一个线程进入可升级的读模式。
4、通过默认构造函数创建的读写锁是不支持递归的,若想支持递归 可通过构造 ReaderWriterLockSlim(LockRecursionPolicy) 创建实例。
5、对于同一把锁、同一线程不可两次进入同一锁状态(开启递归后可以)
6、对于同一把锁、即便开启了递归、也不可以在进入读模式后再次进入写模式或者可升级的读模式(在这之前必须退出读模式)。
7、再次强调、不建议启用递归。
8、读写锁具有线程关联性,即两个线程间拥有的锁的状态相互独立不受影响、并且不能相互修改其锁的状态。
9、升级状态:在进入可升级的读模式 EnterUpgradeableReadLock后,可在恰当时间点通过EnterWriteLock进入写模式。
10、降级状态:可升级的读模式可以降级为读模式:即在进入可升级的读模式EnterUpgradeableReadLock后, 通过首先调用读取模式EnterReadLock方法,然后再调用 ExitUpgradeableReadLock 方法。

实现code如下:

	int coutn = 0;
    /// <summary>
    /// 将异常或信息写入日志
    public override void WriteLine(string exception, string message)
    {
        
        //读写锁,当资源处于写入模式时,其他线程写入需要等待本次写入结束之后才能继续写入
        ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();
        try
        {
            coutn++;
            //设置读写锁为写入模式独占资源,其他写入请求需要等待本次写入结束之后才能继续写入
            //注意:长时间持有读线程锁或写线程锁会使其他线程发生饥饿 (starve)。 为了得到最好的性能,需要考虑重新构造应用程序以将写访问的持续时间减少到最小。
            //从性能方面考虑,请求进入写入模式应该紧跟文件操作之前,在此处进入写入模式仅是为了降低代码复杂度
            //因进入与退出写入模式应在同一个try finally语句块内,所以在请求进入写入模式之前不能触发异常,否则释放次数大于请求次数将会触发异常
            LogWriteLock.EnterWriteLock();
            string sMsg = Environment.NewLine + DateTime.Now.ToString() + Environment.NewLine;

            if (!string.IsNullOrEmpty(message))  //如果信息不为空,加在最前面
            {
                sMsg += exception + ":"; // 操作提示
                sMsg += message + "\r\n";  // 操作模型ID
                File.AppendAllText(FileFullPath, sMsg);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("累计出错数:" + coutn);
        }
        finally
        {
            //退出写入模式,释放资源占用
            //注意:一次请求对应一次释放
            //若释放次数大于请求次数将会触发异常[写入锁定未经保持即被释放]
            //若请求处理完成后未释放将会触发异常[此模式不下允许以递归方式获取写入锁定]
            LogWriteLock.ExitWriteLock();
        }

    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值