【问题标题】:How to synchronize multi-threaded calls to the same method如何将多线程调用同步到同一个方法
【发布时间】:2010-09-15 18:43:21
【问题描述】:

我有一个从多个线程调用的方法。每个线程都有自己的类实例。同步访问代码最直接的方法是什么?

我不能只使用lock(obj),其中obj 是实例成员,但是在类上将obj 声明为静态就足够了吗?那么对该方法的所有调用都将锁定在同一个对象上?一个简单的例子如下:

class Foo
{
    static object locker = new object();

    public void Method()
    {
        lock(locker)
        {
            //do work
        }
    }
}

编辑://do work 位正在写入数据库。在这个特定的例子中,为什么我需要对这些写入进行序列化需要 3 页来解释,而且我真的不想重温导致我走到这一步的所有细节。我要做的就是确保每条记录在写入下一条记录之前已完成写入。

【问题讨论】:

  • 如果每个线程都有自己的类实例,如果它不触及实例之间或全局共享的东西,则不需要锁定对方法的调用。如果触摸这样的东西,你应该锁定他们的访问权限,而不是整个方法。
  • 你可以在albahari.com/threading了解很多关于 C# 线程(包括锁)的知识
  • 正确的同步方式是解决同步不正确引起的问题。您在不说明问题的情况下寻求解决方案。 您要解决的问题是什么? 例如,当另一个线程正在修改该状态的一半时,一个线程可能会读取不一致的状态吗?是不是您可能会在 IA64 上观察到彼此无序的读取和写入?说明你要解决的问题,有人可以帮你解决;不要让人们猜测问题出在哪里。
  • 如果需要序列化DB访问,使用更严格的事务隔离级别不是很好的解决方案吗?

标签: c# multithreading


【解决方案1】:

当每个线程都有自己的实例时,为什么需要 any 同步?保护共享的资源,不要为非共享状态而烦恼。这会自动帮助您找到锁定对象的最佳位置。如果它是对象共有的静态成员,那么您确实也需要一个静态锁定对象。

【讨论】:

    【解决方案2】:

    您的示例肯定会起作用,但必须有一些资源在类的不同实例之间共享以使其成为必要。

    【讨论】:

      【解决方案3】:

      您遗漏了最重要的部分:// do work

      中涉及的数据

      如果// do work 使用静态数据,那么您就有了正确的解决方案。

      如果// do work 只使用实例数据,那么您可以完全省略lock() {}(因为1 个实例属于1 个线程)或使用非静态locker(1 个实例,多个线程)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-20
        • 1970-01-01
        • 1970-01-01
        • 2012-03-20
        • 1970-01-01
        相关资源
        最近更新 更多