应该在列表本身还是在锁定对象上同步?

时间:2014-08-12 09:15:37

标签: java synchronization synchronized

一段时间以来,我脑子里有一个问题:当多个线程有权访问该列表时,如何同步访问列表(ArrayList ...)更安全?在列表本身上同步是否更安全,或者创建锁定对象并使用它来同步它更安全?

4 个答案:

答案 0 :(得分:5)

无需自行同步。集合框架已经做到了。只是利用它。

List list = Collections.synchronizedList(yourList);

并使用返回的list。请记住方法

  

返回由指定列表支持的同步(线程安全)列表。

答案 1 :(得分:4)

我相信这就是你想要的。可能有2个案例(最终):

您使用单独的锁定进行同步。

someMethod(){
synchronized(lock){
// code to access/modify List here
}
}

您可以直接在List实例上进行同步

synchronized(list)
{
// code to access/modify list here
}

如果someMethod()是访问列表的唯一方式,则第一种情况是安全。来自不同流的任何其他线程都可以修改实际列表。

第二种情况会锁定实际的 list 实例,因此,您始终可以保证一次只有一个线程访问/修改列表。

答案 2 :(得分:0)

只要您的锁Objectfinal,两者在安全性方面都是相同的。如果在代码中的多个类上访问List本身,可能会更容易锁定List,因此您不必同时传递ObjectList<T> list = Collections.synchronizedList(new ArrayList<T>)正在同步。
但是你应该避免所有这些并让Java使用{{1}}

为你处理同步

答案 3 :(得分:0)

只要您始终锁定对象,两个选项或多或少都是等效的。因此,列表本身的同步可能更没有错误,因为你不能意外地使用&#34;另一个对象&#34;用于同步。

如前所述,如果您只需要&#34;简单&#34;那么您可以使用syncList = Collections.synchronizedList(yourList)同步......这将是最安全的方式,但是在更通用的同步方案中是不够的,例如&#34; put-if-absent&#34;等等。以下剪辑是 BAD - 不够同步:

if (syncList.contains(element)) { syncList.add(element); }