首页 > 解决方案 > 锁定对象的最佳方法

问题描述

我正在用 C# 构建一个程序,其中有 2 个使用相同对象的线程。第一个线程更新对象值,第二个线程将其打印到 GUI。

我正在寻找实现线程之间锁定机制的最多correct或方法。clean

我在程序中的一个实现示例(不是实际程序):

namespace Test___Console
{
    public class Custom
    {
        public static object lockinObject = new object();
        public string name;
        public int value;
        public Custom(string name)
        {
            this.name = name;
        }
    }
    public class Program
    {
        public static object lockinObject = new object();
        static Thread firstThread;
        static Thread secondThread;
        static public Custom someData;
        static void Main(string[] args)
        {
            someData = new Custom("first");
            firstThread = new Thread(FirstThreadFunctions);
            secondThread = new Thread(SecondThreadFunctions);
            firstThread.Start();
            secondThread.Start();
            do
            {

        } while (true);
    }
    static void FirstThreadFunctions()
    {
        Random rnd = new Random();
        do
        {
            someData.value = rnd.Next();
            Thread.Sleep(1000);
        } while (true);
    }
    static void SecondThreadFunctions()
    {
        do
        {
            Console.WriteLine(someData.value.ToString());
            Thread.Sleep(1000);
        } while (true);
    }
}
}

我想到了 3 种方法来锁定 someData 对象

1.将带有锁定对象的get设置添加到someData对象。

2.将带有锁定对象的设置添加到自定义类变量中。

3.用锁定语句封装所有使用相同数据对象的代码段(我最不喜欢的方法)。

我没有很多编程经验,所以我问你处理这个问题的“正确”或“最干净”的方法是什么。

谢谢

标签: c#multithreadinglocking

解决方案


你想尽可能地限制你的阻塞代码。让我们以你的情况为例。

实际上,您要做的是锁定一个对象并防止它在写入时读取。从其他阅读器阅读时无需锁定它。

ReaderWriterLockslim到resue。然后在你的Custom课上

public class Custom
{
    private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim();

    private int currvalue;
    public int value {
        get {
            cacheLock.EnterReadLock();
            var retValue = currvalue;
            cacheLock.ExitReadLock();
            return retValue;
        }
        set {
            cacheLock.EnterWriteLock();
            this.currvalue = value;
            cacheLock.ExitWriteLock();
        }
    } 
}

这样,您将并发性限制为仅需要线程安全的当前对象,锁被非常紧密地应用于数据,因此不会轻易引入死锁并且仅用于写入操作。


推荐阅读