多线程:锁定对象类型之间的差异

时间:2014-07-22 19:59:59

标签: c# .net multithreading thread-safety

请解释这两种锁定方式之间的区别。

我有一个List我想访问线程安全:

var tasks = new List<string>();

1

var locker = new object();
lock (locker)
{
    tasks.Add("work 1");
}

2

lock (tasks)
{
    tasks.Add("work 2");
}

我的想法:

  1. 防止两个不同的线程同时运行锁定的代码块。
  2. 但是如果另一个线程运行的是另一个尝试访问task的方法 - 这种类型的lock不会有帮助。

    1. 阻止List<>个实例,以便其他方法中的其他线程被阻止,直到我解锁tasks
    2. 我是对还是错?

2 个答案:

答案 0 :(得分:2)

(2)仅阻止显式调用lock (tasks)的其他代码。通常,只有当您知道任务是私有字段时才应该执行此操作,因此可以在整个类中强制lock (tasks)表示锁定列表上的操作。当锁在概念上与对集合的访问链接时,这可以是一个很好的快捷方式,您不必担心锁的公开暴露。但是你不能“免费”获得这个;它需要明确使用,就像锁定任何其他对象一样。

答案 1 :(得分:1)

他们做同样的事情。尝试修改列表而不锁定同一对象的任何其他代码都将导致潜在的竞争条件。

更好的方法可能是在对基础列表执行任何操作之前将列表封装在另一个获取锁的对象中,然后任何其他代码都可以简单地调用包装器对象上的方法,而不必担心获取锁。