我希望能帮助理解一个概念。对于不当使用术语,我深表歉意。我是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;
}
}
现在让我们假设我们在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()访问?
感谢您的时间和耐心。
答案 0 :(得分:7)
如果objA正在使用myFunction,我理解objB由于锁定而无法同时使用myFunction。
要明确:这里的objA和objB是“在线程A上调用”和“在线程B上调用”的简写。
你的陈述基本上是正确的;我们可以更清晰地说,如果线程A 获取锁,那么线程B尝试获取锁将阻塞,直到线程A释放锁定为止。< / p>
另请注意,无法保证锁定是公平的。如果线程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。如果这听起来像是一个容易写的错误,就是。
多线程超级强硬,如果你不小心,你可以很容易地同时在浴缸里结束很多人。这听起来不像听起来那么有趣,因为他们都没有同意水是否应该运行,也许其中一些人正试图清理那个桶,而有人在里面,这是一个混乱,崩溃你的过程和丢失用户的数据。
答案 1 :(得分:0)
可以objB使用secondFunction()吗?
是的,但会造成混乱。
什么是更好的惯例?
一般情况下,sorted
但唯一重要的是其他代码可能会锁定集合。
如果我使用lock(_lock),在myfunction()中,它是否仍会保护myCollection
没有。访问(非线程安全)myCollection的所有代码都需要首先锁定同一个锁对象。如果它是lock(_lock)
或_lock
并不重要,只要它始终是同一个对象。