我应该在多线程范例中锁定数据表吗?

时间:2013-11-26 14:24:44

标签: c# multithreading caching

在Windows服务项目(C#.Net Platform)中,我需要一个建议 在项目中,我有一个名为Cache的类,其中我保留了一些我经常需要的数据。有一个线程在每30分钟后更新缓存。哪里有多个线程使用缓存数据 在缓存类中,有getter和setter函数,分别由用户线程和缓存更新程序线程使用。没有人直接使用像表这样的数据对象,因为它们是私有成员 从上面的上下文来看,你认为我应该在缓存类中使用锁定功能吗?

2 个答案:

答案 0 :(得分:1)

写入共享内存位置(如缓存)时不使用锁的效果实际上取决于应用程序。如果代码用于银行软件,结果可能是灾难性的。

通常大拇指 - 当多个线程访问同一位置时,即使只有一个脚踏写入而所有其他线程都在读取,您应该使用锁定(用于写入操作)。可能发生的是,一个线程将开始读取数据,被更新程序线程刷出;因此,最终可能会混合使用新旧数据。如果这真的是一个影响取决于应用程序和它是多么明智。

答案 1 :(得分:1)

关键点:如果您没有锁定读取,则您的读取可能无法看到更改。锁定将强制您的读取代码从主存储器获取值,而不是从缓存或寄存器中提取数据。为了避免实际锁定,您可以使用Thread.MemoryBarrier(),它将执行相同的工作,而不会产生实际锁定任何内容的开销。

次要要点:使用锁定会阻止读取获取一半旧数据和一半新数据。如果您正在阅读多个字段,我建议您这样做。如果你真的很聪明,你可以将所有数据保存在一个不可变对象中,并将该对象返回给任何调用getter的人,这样就不需要锁。 (当有新数据进入时,你创建一个新的不可变对象,然后一次性用新的替换旧的。如果你仍然感觉很聪明,请使用锁定实际写入 ,使该字段引用对象volatile。)

另外:当你的getter被调用时,记住它正在许多其他线程上运行。有一种倾向认为,一旦运行Cache类的代码,它就在同一个线程上,并且不是