我一直在阅读,并且我是否应该在属性上使用synclock来得到相互矛盾的答案。
我有一个多线程应用程序,需要跨实例对象的线程获取/设置属性。它目前没有使用synclock实现,到目前为止我没有发现任何问题。我在常见的静态方法上使用synclock,但我想以线程安全的方式正确实现我的实例类。
非常感谢任何反馈。
答案 0 :(得分:3)
一个好的经验法则是,如果满足以下任何条件,您需要锁定:
然后你可能需要锁定访问这些字段的每个方法或属性。
编辑:请记住,锁定类内部的内容很少 - 您需要做的是确保在整个的范围内不会出错逻辑运算。
正如@Bevan指出的那样,如果调用代码需要多次访问一个对象,那么客户端代码应该在整个工作期间对该对象取出自己的锁,以确保另一个线程不会“在“它的访问和弄乱它的逻辑之间。”
如果需要同时取出多重锁,您还需要注意,它们始终以相同的顺序 。如果线程1在实例A上有一个锁并试图锁定实例B,并且线程2在实例B上有一个锁并试图在实例A上获得一个锁,则两个线程都被卡住而无法继续 - 你有一个死锁。
答案 1 :(得分:2)
只有使用锁定各个方法,才能使对象线程安全。你最终做的就是序列化(减慢)对象的访问。
考虑这个小例子:
var myObject = ...
var myThreadSafeList = ...
if (!myThreadSafeList.Contains(myObject))
{
myThreadSafeList.Add(myObject);
}
即使myThreadSafeList锁定了每个方法,这也不是线程安全的,因为另一个线程可以在<{1}}和 如果是此列表,则需要其他方法: 只有将逻辑移动到对象中,才能使用锁定操作并使其安全。 如果没有进一步的细节,很难再发表评论,但我建议如下: 举例说明:Contains()
的调用之间改变列表的内容。 / p>
Add()
:AddIfMissing()
var myObject = ...
var myThreadSafeList = ...
myThreadSafeList.AddIfMissing(myObject);