在c#中lock()函数是如何工作的

本文关键字:何工作 工作 函数 lock | 更新日期: 2023-09-27 18:07:55

我有一些c#代码,看起来像这样:

if (cache[filename] != null) {
    return (AppSettings)cache[filename];
}
lock (thisLock)
{
    using (StreamReader sr = new StreamReader(filename))
    {
        instance = (AppSettings)serial.Deserialize(sr);
        cache.Insert(filename, instance, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration);
    }
}
return (AppSettings)cache[filename];

所以,我对锁的理解是,一旦它变成"解锁",那么代码块将被执行。所以在上面的代码中,我假设我需要在锁代码块中再检查一次,看看对象是否已经创建?

我如何检查死锁?

在c#中lock()函数是如何工作的

lock指令将阻止任何其他线程进入,而另一个线程正在处理。你可以使用它来保护非线程安全的资源。

在你的例子中,字典cache是你想要保护的,因为如果多个线程在其中添加,更改和删除元素,你的程序几乎肯定会崩溃。

为了保护cache,您需要将整个操作包装在lock语句中,如下所示:

AppSettings result = null;
lock (thisLock)
{
    if (cache[filename] != null) {
        result = (AppSettings)cache[filename];
    }
    else
    {
        using (StreamReader sr = new StreamReader(filename))
        {
            instance = (AppSettings)serial.Deserialize(sr);
            cache.Insert(filename, instance, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration);
        }
        result = (AppSettings)cache[filename];
    }
}
return result;
所以在上面的代码中,我假设我需要在锁代码块中再检查一次,看看对象是否已经创建?

是的。如果两个线程都检查并发现缓存项丢失,您希望其中一个线程执行在缓存中创建项的昂贵工作,而不是两个线程,因此您需要在锁的内部再次应用相同的检查。这就是著名的"双重检查锁定"模式。

我如何检查死锁?

我看到你的代码有死锁的唯一方法是,如果其他线程持有你想要访问的文件上的锁,并且它正在等待lock块内的一些线程来做其他它想做的事情。那将是一个僵局。如果您确保此代码是访问该文件的唯一代码,或者访问该文件的任何内容都不会依赖于该线程,那么(给定您所展示的代码)您就会很好。