微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

班级围栏 - 单个作者多个读者

如何解决班级围栏 - 单个作者多个读者

对 C# 中的锁定还有另一个困惑。

问题是在不同线程之间共享一个状态。

以下场景:

一个线程处理一个状态机。例如,这台机器会延迟计算一个值。机器线程读取该值并递增。其他线程现在应该能够读取这个计数值。实际上我有更多的值而不仅仅是一个计数,所以我准备了一个包含共享值的类。这看起来像这样:

IStatus一个合适的私有接口。摘要删除,因为不是英文。

    public class Status : ICloneable,IStatus
    {
      private object locker;

      public bool Run { get; private set; }

      public uint SecondRemain { get; private set; }

      // ... and some more value types

      public Status()
      {
        locker = new object();
      }
      
      void IStatus.SetRun(bool enable)
      {
        lock (locker)
        {
          Run = enable;
        }
      }
      
      void IStatus.SetSecondRemain (uint value)
      {
        lock (locker)
        {
          SecondRemain = value;
        }
      }

      // ... and some more set of value types

      public object Clone()
      {
        object copy;
        lock (locker)
        {
          copy = MemberwiseClone();

          // Since it is a "new" object,we decouple the lock
          ((Status)copy).locker = new object();
        }
        return copy;
      }

在状态机及其线程所在的主类中:

private Status shared;

// Shall be accessible by any thread at any time

public Status GetStatus()
{
  // Clones thread-safe,fenced by locker
  return (Status) shared.Clone();
}

// Will be accessed only by inner thread
private void AnyMethodCalledStateMachineThread()
{
  // Get the current remaining second value.
  // No fence here ??
  uint value = shared.SecondRemain;
  
  // fences by locker 
  ((IStatus) shared).SetSecondRemain (value++);
}

我们现在看到的是,只有内部线程会读写一些值。该线程将读取它之前编写的内容。为了确保其他线程可以读取它,它被锁定。

外部线程只能通过lock语句获取完整副本。

但是在读取单个属性时,内部线程本身是否也需要锁定,还是我必须在这属性周围放置锁定(带有额外字段)?

编辑

这是运行线程的请求类型

var thread;

private void Start()
{
  thread = new Thread(new ThreadStart(ProducerMain));
  thread.Start(); 
}

// Example,no real code
private void ProducerMain()
{
  while ( ...)
  {

    Thread.Sleep(1000);

    AnyMethodCalledStateMachineThread();

  }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。