所以我们假设我们有A类和B类。创建了多个A类实例,每个实例都在自己的线程上运行。让我们假设B类中有一堆资源都是A类的实例需要访问,但我只希望一次操作这些资源的一个线程。显而易见的选择是锁定声明。
我的问题是,锁是否应该在B类(对于资源的获取者和设置者),或者它是否在A类本身中是相同的? (如下图所示)
class A
{
B b;
public A(B _b)
{
b = _b;
}
void DoStuff()
{
lock (this)
{
b.resource = "new values"
}
}
}
我希望问题很清楚。请询问您是否需要更多详细信息。
答案 0 :(得分:2)
首先,不要锁定this
。这只会引发僵局
让A
每个锁定自己或他们自己的对象的实例都不起作用。
object lockObject = new object();
锁定。 在您的情况下,第2点)表示锁定对象应该是B
的私有成员。
然后,您仍然需要正确编写所有B
方法。
答案 1 :(得分:0)
假设你说:
but I want only one thread manipulating those resources at one time
然后,是的,他们需要在班级B
。对于当前示例在A
课程中是公平的,但由于B
是公共课,其他一些队友可以决定使用您的B
课程及其资源,如果您不喜欢不提供用于锁定的界面,那么您对报价的要求将不会得到满足
答案 2 :(得分:0)
如果你想从ONLY A访问B的资源(假设有一个类A的sinle实例!,如果没有那么你有问题,因为每个A对象使用uits自己的锁对象 - 这个 - 这是无用的),我认为这是一个选择问题。两者都适用于这种情况。但是,无论何时需要从其他类访问B的资源,这都是有意义的。例如,你有C级访问B的资源。然后,你在A类中的锁在这里不起作用。问题是您在lock语句中使用的对象。以不同的方式思考并将对象放在B中,而不是放在A或其他类中。而不是A类中的语句锁(this),而是进行同步。 B中的对象,可以在锁定语句中使用。例如:
void DoStuff()
{
lock (b.LockObject)
{
b.resource = "new values"
}
}
正如您所说,您还可以在资源getter / setter中使用lock语句。通过这种方式,您无需在需要时记住锁定B对象,尤其是在不同的类中使用(当然不是A)。我想,最终的选择是设计选择。如果您还需要非线程安全版本的资源getter / setter,使用上面的示例更有意义。