【问题标题】:Shared Interface and ReaderWriterLockSlim共享接口和 ReaderWriterLockSlim
【发布时间】:2009-08-27 20:33:29
【问题描述】:

我在一个有多个线程的类中使用 log4net,我有一个简单的问题。在log4net.ILog接口上查看属性和调用方法时需要输入readlock/writelock吗?

我正在使用 log4net 示例中的建议方法,所以在所述类的顶部我有:

Private Shared ReadOnly log As log4net.ILog = log4net.LogManager.GetLogger(decType) 

由于该类涉及与其交互的多个线程,因此我有一个ReaderWriterLockSlim 实例,用于确保我的变量不会进入任何竞争条件。所以回顾一下,如果我想确保我正在练习安全线程,我需要做这样的事情:

If Me.ReaderWriterLockSlim.TryEnterUpgradableReadLock(-1) Then
  If log.IsWarnEnabled Then
    If Me.ReaderWriterLockSlim.TryEnterWriteLock(-1) Then
      log.Warn("Log Message Here")
      Me.ReaderWriterLockSlim.ExitWriteLock()
    End If
  End If
  Me.ReaderWriterLockSlim.ExitUpgradeableReadLock()
End If

或者,我可以简单地这样做吗:

If log.IsWarnEnabled Then log.Warn("Log Message Here")

附:是的,这是粗略的伪代码,我实际上没有名为“ReaderWriterLockSlim”的ReaderWriterLockSlim 实例。

【问题讨论】:

  • 感谢 Steven 的编辑,我最近做了很多 linux 工作。哦,因为我无法抗拒:“sudo make [steven] a sandwhich”。

标签: .net vb.net multithreading log4net thread-safety


【解决方案1】:

所以你基本上想知道 log4net 是否线程安全?

来自FAQ

是的,log4net 是线程安全的。

所以你可以简单地这样做:

If log.IsWarnEnabled Then log.Warn("Log Message Here")

【讨论】:

  • 我想确保它仍然是线程安全的,即使在多线程类中将其用作共享对象时也是如此。我确实从网页上读到了它,但由于我需要使用它的方式对我来说似乎是一个边缘案例,我想确保我仍然是(线程)安全的。
  • “线程安全”的定义(当应用于 .NET 类/方法时)是“从多个线程同时使用安全”。关于它是共享对象的部分是无关紧要的。
  • 如果某些东西被称为“线程安全”,这意味着可以在多线程类中的共享对象上调用各个方法,而无需额外的同步代码。当然,如果IsWarnEnabled 的返回值在IfThen 之间变化,您的示例可能会产生不需要的日志消息。
  • 鉴于日志消息本身是恒定的,因此检查 log.IsWarnEnabled 是没有意义的。只需拨打 log.Warn 电话。如果未启用记录器,log4net 仍会将其过滤掉。如果你做了一些昂贵的事情来构建日志消息,你只需要检查 IsXXXEnabled。
【解决方案2】:

在上面的示例中,您不需要输入写锁,因为您没有更改 IsWarnEnabled 的值。此外,无限超时调用 TryEnterWriteLock 也没有任何意义 - 您也可以调用 ReaderWriterLockSlim.EnterWriteLock。因此,即使 Log4Net 不是线程安全的(正如其他人提到的那样),您只需要编写:

readerWriterLock.EnterReadLock();
try
{
  if(log.IsWarnEnabled)
    log.Warn("log message here");
}
finally
{
  readerWriterLock.ExitReadLock();
}

然后,您将在更改 log.IsWarnEnabled 的值时输入写锁。

【讨论】:

  • 重点在图案中。通过遵循该模式,我可以轻松实现超时值(除了 -1)而无需重构。
  • 当然,我只是想为任何来到这里并复制并粘贴您的代码的人清理一下 :-)
  • 有道理,非常感谢尼克!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-23
  • 1970-01-01
  • 2019-02-01
  • 2018-03-21
  • 2016-03-15
  • 1970-01-01
相关资源
最近更新 更多