相关疑难解决方法(0)

双重锁定中的记忆模型保证

我最近在Resharper网站上看到了以下帖子.这是对双重检查锁定的讨论,并具有以下代码:

public class Foo
{
    private static volatile Foo instance;
    private static readonly object padlock = new object();

    public static Foo GetValue()
    {
        if (instance == null)
        {
            lock (padlock)
            {
                if (instance == null)
                {
                    instance = new Foo();
                    instance.Init();
                }
            }
        }
        return instance;
     }

     private void Init()
     {
        ...
     }
}
Run Code Online (Sandbox Code Playgroud)

该帖子然后声称

如果我们假设Init()是用于初始化Foo状态的方法,那么由于内存模型不能保证读写顺序,上述代码可能无法按预期运行.因此,对Init()的调用实际上可能在变量实例处于一致状态之前发生.

这是我的问题:

  1. 我的理解是,.NET内存模型(至少从2.0开始)并没有要求instance被声明为volatile,因为lock它将提供一个完整的内存栅栏.是不是这样,还是我被误导了?

  2. 对于多个线程,是不是只对可观察的读/写重新排序?我的理解是,在一个线程上,副作用将是一致的顺序,并且lock就地防止任何其他线程观察到某些东西是不对的.我也在这里吗?

.net multithreading

12
推荐指数
2
解决办法
2484
查看次数

Monitor.Exit() 上的 SynchronizationLockException?

我正在使用 Monitor 类来管理关键部分。但有时我会遇到SynchronizationLockException以下消息

An unhandled exception of type 'System.Threading.SynchronizationLockException' occurred in ManagedType.dll
Additional information: Object synchronization method was called from an unsynchronized block of code.
Run Code Online (Sandbox Code Playgroud)

我的代码在下面

Object^ lockObj = gcnew Object(); //Global variable
bool GetValue()
{
    try
    {
        Monitor::Enter(lockObj);
        return this.value;
    }
    finally
    {
        Monitor::Exit(lockObj);
    }
}
Run Code Online (Sandbox Code Playgroud)

SynchronizationLockException抛出时Monitor::Exit(lockObj)调用。

我已经在这个论坛和互联网上搜索过,但包括 MSDN 在内的大多数主题都说“当您尝试在 Monitor.Enter() 和 Monitor.Exit() 中使用值类型变量而不是引用类型时,将抛出此异常”。

但就我而言,我使用 lockObj 作为引用对象。所以我不知道为什么它会抛出这个异常。有人可以帮助我吗?

非常感谢,

T&T集团!

c++-cli managed visual-studio

2
推荐指数
1
解决办法
3231
查看次数

标签 统计

.net ×1

c++-cli ×1

managed ×1

multithreading ×1

visual-studio ×1