ReaderWriterLockSlim和引用

时间:2016-10-21 23:49:46

标签: c# multithreading

我有一个班级:

public static class Message
{
    private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
    private static string theMessage;

    public static void SetMessage(string message)
    {
        Locker.EnterWriteLock();
        theMessage = message;
        Locker.ExitWriteLock();
    }

    public static string GetMessage()
    {
        Locker.EnterReadLock();
        var msg = theMessage; // <<<=====
        Locker.ExitReadLock();
        return msg;
    }
}

如果我理解正确,请在指尖的行中创建对theMessage的引用,然后返回它。然后多个线程将访问同一个变量,或者我错了?

我是否需要调用string.Copy来确保它是线程安全的?

由于

2 个答案:

答案 0 :(得分:2)

基于对象的类(字符串为1)的成员赋值在C#中是原子的。根本不需要锁定。

如果您在两个块中有更多的代码而不是theMessage = message;var msg = theMessage;,则可能需要它,但因为您只做了一次分配,所以不需要锁定。

答案 1 :(得分:2)

因为string是一个引用类型,所以你要引用一个值,而不是这行中的值本身:

header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', FALSE);
header('Pragma: no-cache');

如果你想阻止来自其他线程的更改影响大多数引用类型的方法的返回值,我建议你复制该值并返回另一个对新复制值的引用。
但是字符串是不可变的类型所以它并不重要,因为无论如何其他线程不能改变它的值(没有人可以是不可变的!)。

因此,您不必深度复制字符串以防止其他线程更改返回值。

您可以引用这些问题(12)以进一步阅读为什么不可变对象是线程安全的。