15

我有这三种方法的一堂课。这个类被许多线程使用。如果 Method2 和/或 Method3 在任何线程中运行,我希望 Method1 等待。有什么建议么?

public class Class1
{
    public static void Method1() 
    {
        Object lockThis = new Object();

        lock (lockThis)
        {
            //Body function
        }
    }

    public static void Method2() 
    {
         //Body function
    }

    public static void Method3() 
    {
         //Body function
    }
}
4

4 回答 4

19

如果我理解正确,你需要这样的东西:

static object lockMethod2 = new object();
static object lockMethod3 = new object();

public static void Method1() 
{
    lock (lockMethod2)
    lock (lockMethod3)
    {
        //Body function
    }
}

public static void Method2() 
{
    lock (lockMethod2)
    {
        //Body function
    }
}

public static void Method3() 
{
    lock (lockMethod3)
    {
        //Body function
    }
}

这允许 method3 在 method2 正在运行时执行,反之亦然,而 method1 必须等待两者。当然,method2 和 3 不会在 1 运行时运行。

于 2013-02-20T10:09:48.757 回答
14

当前的锁实现完全没用,因为每个线程都会锁在不同的对象上。
锁定通常使用只读字段完成,该字段仅初始化一次。
像这样,您可以轻松锁定多个方法:

public class Class1
{
    private static readonly object _syncRoot = new object();

    public static void Method1() 
    {
        lock (_syncRoot)
        {
            //Body function
        }
    }

    public static void Method2() 
    {
        lock (_syncRoot)
        {
            //Body function
        }
    }

    public static void Method3() 
    {
        lock (_syncRoot)
        {
            //Body function
        }
    }
}
于 2013-02-20T10:09:51.997 回答
12

我建议一个ReaderWriterLockSlimhttp://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

与读取操作类似,方法 2 和方法 3 可能并行发生,而方法 1(如写入操作)需要等待它们完成。这不是常规的读写并发情况,但逻辑是相似的。

public class Class1
{
    private ReaderWriterLockSlim methodLock = new ReaderWriterLockSlim();
    public static void Method1() 
    {
        methodLock.EnterWriteLock();
        try
        {
            //Body function
        }
        finally
        {
            methodLock.ExitWriteLock();
        }
    }

    public static void Method2() 
    {
         methodLock.EnterReadLock();
        try
        {
            //Body function
        }
        finally
        {
            methodLock.ExitReadLock();
        }
    }

    public static void Method3() 
    {
         methodLock.EnterReadLock();
        try
        {
            //Body function
        }
        finally
        {
            methodLock.ExitReadLock();
        }
    }
}
于 2013-02-20T10:13:32.543 回答
3

如果您是多线程,那么lock所有线程都必须可以访问。因此,在这种情况下,您的锁需要是静态的,静态方法才能看到它。

您当前的设置将为每个线程创建一个新的锁定对象。因此,提供 now 同步。

于 2013-02-20T10:08:50.720 回答