C#:线程安全功能

时间:2009-02-17 10:23:48

标签: c#

以下哪个代码更适合多线程访问函数的情况

public ArrayList CallMe1()
    {
        ArrayList al = new ArrayList();

        lock(al.SyncRoot)
        {
            al.Add("33");
            al.Add("45");

            return al;
        }

    }

    public ArrayList CallMe2()
    {

        ArrayList al = new ArrayList();

        Monitor.Enter(al);

        al.Add("33");
        al.Add("45");
        Monitor.Exit(al);

        return al;


    }

7 个答案:

答案 0 :(得分:9)

在这种情况下没有共享状态,因此不需要同步。

但是,假设arraylist 共享状态,则以下情况适用:

它们都是相同的(lock implements Monitor internally)。

晴。

您的第二个版本需要在finally块中释放监视器,否则如果代码抛出异常,锁将永远不会被释放并导致应用程序死锁。

总之,请使用第一个版本(lock (...) {... })以避免不必要的输入和可能的错误。

答案 1 :(得分:8)

都不是。函数不共享任何数据,因此不需要同步。

答案 2 :(得分:6)

都不是。您的所有函数都没有共享状态(只有局部变量),这使得它们本身就是可重入的。无论如何都不需要同步。

答案 3 :(得分:1)

正如其他答案所述,锁定使用监视器,但它比第二个例子更好。它更好的是它在try finally块中包含对monitor的调用,以确保在有异常的情况下释放锁。

出于这个原因,我建议你几乎所有操作都使用锁。

答案 4 :(得分:1)

1 - 你这里不需要任何锁定。

2 - 如果可以使用锁定,请不要使用Monitor。

3 - 在第一个例子中,您正在锁定一个SyncRoot对象,它比锁定一个数组更好。

答案 5 :(得分:0)

您还可以找到答案的一部分here

返回语句内部(CallMe1)或外部(CallMe2)锁也没有区别。

答案 6 :(得分:-2)

<。> .net lock 的问题是,如果发生死锁,它不会抛出任何异常或任何异常。

顺便说一句,每次都要锁定新创建的ArrayList。这应该如何帮助?我更喜欢在某处创建一个静态对象并对其进行锁定。