同步 ArrayList 与同步方法块

synchronized ArrayList vs synchronized method block

我有 2 个代码片段,它们将做同样的事情,使线程安全。第一个使用 Collections.synchronizedList,示例:

DataServiceRequest request = Collections.synchronizedList(new ArrayList<DataServiceRequest>());

第二个通过同步方法做同样的事情,示例:

public synchronized void addRequest(DataServiceRequest request) {
   this.getRequests().add(request);
}

与上述 2 个示例的性能相比,最有效和最安全的方法是什么?

第一个实际上只是第二个的语法糖(它 returns 一个包装器列表,将 synchronized (mutex) 放在每个调用周围),因此从性能角度来看不太可能有任何区别查看。

至于 "which is the safest way" - 这取决于您的编码标准。使用时一定要注意Collections.synchronizedList的文档,特别是:

it is critical that all access to the backing list is accomplished through the returned list.

It is imperative that the user manually synchronize on the returned list when iterating over it

迭代您控制其同步的列表时,您仍然会遇到同样的问题 - 这只是说 synchronizedList 使用的互斥量是列表本身。如果您控制同步,您只需要始终如一地使用相同的互斥体来实现对支持列表的所有线程安全访问。

您的问题可能暗示您不打算同步 所有 列表操作,而不仅仅是那些更改列表的操作。如果是这样,那么这就是错误的想法。但即使不是这样,使用 synchronizedList 包装器也可以消除您的程序的担忧,因为它保证所有方法调用都是同步的。

synchronizedList 无法保证的一件事是使用列表迭代器的代码块的同步。这仍然是您需要在自己的同步块中完成的事情。