线程和锁定资源

Tim*_*Tim 1 c# multithreading locking

我希望能帮助理解一个概念.对于不当使用术语,我深表歉意.我是OOP的新手,所以请耐心等待我.

这是一些显示问题的伪代码:

public MyClass
{
    myClass singleton; //singleton object of myClass (only one instance created)
    myCollection; //list or array
    private object _lock;

    public myFunction()
    {
        lock(myCollection) //or do I use lock(_lock)?
        {
            try
            {
                //modifies my collection
            }
            catch
            {
                //exception
            }
        }
    }

    public secondFunction()
    {
        //modify my collection
    }

    public getMyCollection()
    {
        return myCollection;
    }

}
Run Code Online (Sandbox Code Playgroud)

现在让我们假设我们在classA和classB(我将调用这些对象objA和objB)的不同线程上有两个对象,它们正在尝试访问MyClass.

1)如果objA正在使用myFunction,我理解objB由于锁定而无法同时使用myFunction.

但是,objB可以使用secondFunction()吗?或者myFunction()上的锁是否保护myCollection不会被修改,直到锁被释放?

如果上述问题为真:如果objA正在使用myFunction(),并且objB正在尝试使用secondFunction(),那么objB线程是否会等到锁被释放?

2)什么是更好的惯例?锁定(_lock)或锁定(myCollection)

3)如果我在myfunction()中使用lock(_lock),它是否仍会保护myCollection不被secondFunction()访​​问?

感谢您的时间和耐心.

Eri*_*ert 7

如果objA正在使用myFunction,我理解objB由于锁定而无法同时使用myFunction.

要清楚:objA和objB这里是"在线程A上调用"和"在线程B上调用"的简写.

你的陈述基本上是正确的; 我们可以更清晰,并说如果线程A 获得锁定,那么线程B 获取锁定的尝试将阻塞,直到线程A释放锁定为止.

另请注意,无法保证锁定是公平的.如果线程C尝试在线程B之后获取锁定,则无法保证线程B在线程A释放它时获取它.线程C可以先行.

想想这样.你有一片沙漠.在沙漠中间是一个浴缸.没有墙.浴缸旁边有一扇门.门有锁.规则是:如果您想使用浴缸并且门已解锁,请锁上门,洗个澡,打开门.如果您想使用浴缸并且门被锁定,请等待它解锁.如果有多个人在等待,那么选择一个人通过一些未指定的机制赢得比赛.

但是,objB可以使用secondFunction()吗?

当然.无论门是否锁定,这都违反规则并跳入浴缸.记住,没有墙.

或者myFunction()上的锁是否保护myCollection不会被修改,直到锁被释放?

一点也不.什么都没有阻止myCollection被修改,除了在每个可以修改的地方放置相同的.也就是说,如果他们想要使用浴缸,则要求每个人都在门口等.

如果objA正在使用myFunction(),并且objB正在尝试使用secondFunction(),那么objB线程是否会等到锁被释放?

没有; secondFunction中没有锁定.

再次回到基本面.锁可以由线程获取,并且可以由获取它的线程释放.锁定可以由同一个线程多次获取而不释放它.一旦所有获取都具有相应的释放,则任何其他线程都可以自由获取锁.

为了你的目的,就是这样.锁非常非常简单.你获得它们,如果你无法获得它们,你可以阻止它们,一旦你获得锁定,你需要在不久之后释放它以给别人一个转弯.

有更复杂的方法来使用锁,但从基础开始.

什么是更好的惯例?锁定(_lock)或锁定(myCollection)

始终锁定专用的专用对象,除了锁定之外什么都不用.如果你偏离这种最佳实践,有许多方法可能会出现严重错误.

特别是永远不会锁定Type,打开string或打开this.

如果我在myfunction()中使用lock(_lock),它是否仍会保护myCollection不被secondFunction()访​​问?

不.再次回到锁定的定义.锁定语句尝试获取锁定.这一切,它确实.如果你在其他地方有一些其他功能,在需要的时候没有获得锁定,那么这就是一个bug.如果这听起来像一个容易写的bug,那就是.

多线程是非常难的,如果你不小心,你可以很容易地同时在浴缸里结束很多人.这是比它听起来那么好玩了,因为他们没有对水是否应该运行与否,也许有些人正试图以清洁工作桶,同时还有人在其同意,并且它是崩溃的过程很乱,丢失用户的数据.

  • @Tim:我不能强调*多线程在现代硬件上很难*.多线程为您提供了一个世界,在这个世界中,您必须假设所有内存都被修改,除非某些东西保持不变*.它给你一个世界,*两个线程可以不同意变量变异的顺序*.基本上,你认为你对程序了解的一切都是错误的.不要陷入认为任何部分容易的陷阱. (2认同)
  • @Tim:哦,但情况变得更糟.我们给你驯服这个问题的主要工具是锁,这是一个可怕的工具; 它要求你拥有**程序中所有锁的全局知识**才能正确使用它,所以你通常的技巧是将小问题的小正确解决方案组合成大问题的大型正确解决方案不再有效.我的建议是尽可能避免多线程. (2认同)