我所说的锁定助手指的是一次性对象,可以通过它来实现锁定using
声明。例如,考虑一个典型的用法SyncLock
班级来自乔恩·斯基特的 MiscUtil:
public class Example
{
private readonly SyncLock _padlock;
public Example()
{
_padlock = new SyncLock();
}
public void ConcurrentMethod()
{
using (_padlock.Lock())
{
// Now own the padlock - do concurrent stuff
}
}
}
现在,考虑以下用法:
var example = new Example();
new Thread(example.ConcurrentMethod).Start();
我的问题是这样的 - 因为example
在一个线程上创建并且ConcurrentMethod
被另一个人调用,不能ConcurrentMethod
的话题被忽视_padock
构造函数中的赋值(由于线程缓存/读写重新排序),因此抛出NullReferenceException
(on _padLock
本身)?
我知道锁定Monitor
/lock
具有内存屏障的好处,但是当使用诸如此类的锁助手时,我不明白为什么可以保证这样的屏障。在这种情况下,据我了解,必须修改构造函数:
public Example()
{
_padlock = new SyncLock();
Thread.MemoryBarrier();
}
Source: 了解多线程应用程序中低锁技术的影响
EDITHans Passant 认为线程的创建意味着内存屏障。那么怎么样:
var example = new Example();
ThreadPool.QueueUserWorkItem(s => example.ConcurrentMethod());
现在不一定要创建线程......
不,您不需要做任何特殊的事情来保证创建内存屏障。这是因为几乎所有用于让方法在另一个线程上执行的机制都会产生一个释放栅栏调用线程上的屏障和获取栅栏工作线程上的屏障(实际上它们可能是完整的栅栏屏障)。所以要么QueueUserWorkItem
or Thread.Start
会自动插入必要的障碍。您的代码是安全的。
另外,作为切向利益的问题Thread.Sleep
还会产生内存屏障。这很有趣,因为有些人天真地使用Thread.Sleep
模拟线程交错。如果此策略用于解决低锁代码问题,那么它可以很好地掩盖您试图查找的问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)