3

我有一种方法可以同步访问 myst,一次只允许一个线程通过它。这是我当前的实现:

private Boolean m_NoNeedToProceed;
private Object m_SynchronizationObject = new Object();

public void MyMethod()
{
    lock (m_SynchronizationObject)
    {
        if (m_NoNeedToProceed)
            return;

现在我正在考虑像这样改变它:

private Boolean m_NoNeedToProceed;
private Object m_SynchronizationObject = new Object();

public void MyMethod()
{
    if (m_NoNeedToProceed)
        return;

    lock (m_SynchronizationObject)
    {

在锁定之前快速返回不是更好,这样调用线程就可以继续而不等待前一个线程完成方法调用吗?

4

3 回答 3

1

在锁定之前快速返回不是更好吗...

不,锁不仅仅是一种互斥机制,它还是一个内存屏障1。如果没有锁,如果任何并发线程尝试修改变量2 ,您可能会引入数据竞争。

顺便说一句,锁在没有争用时具有良好的性能,因此无论如何您都不会获得太多性能。与往常一样,不要对性能做出假设,尤其是“接近金属”。如有疑问,请测量!

...这样调用线程就可以继续进行而无需等待前一个线程完成方法调用?

这只是意味着您持有锁的时间超过了必要的时间。一旦共享内存不再需要保护(可能比方法退出更早)就释放锁,您不需要尝试人为地规避它。


1 Ie 触发缓存一致性机制,因此所有 CPU 内核都看到“相同”的内存。

2例如,一个线程写入变量,但该更改会在一个内核的写入缓冲区中停留一段时间,因此其他内核上的其他线程不会立即看到它。

于 2013-05-01T19:50:29.280 回答
0

是的,只要m_NoNeedToProceed没有任何与之相关的竞争条件。

如果该方法需要很长时间才能运行,并且某些线程不需要实际访问该方法的临界区。那么最好让他们早点回来,而不是得到锁。

于 2013-05-01T19:33:13.203 回答
0

是的,最好在锁定之前这样做。

使m_NoNeedToProceed 挥发性

只是一个免责声明:volatile不会使它成为线程安全的。它只会导致检查值是否在另一个处理器中发生更改的障碍。

于 2013-05-01T19:33:45.450 回答