java - Util 创建一个在指定互斥体上同步的列表

标签 java list concurrency synchronized

是否有一些实用程序在指定的互斥锁上创建同步列表?喜欢java.util.Collections.synchronizedList(List<T> list, Object mutex)但公开?

最佳答案

没有这样的public方法可以让您控制同步集合将使用的互斥体。因此,如果它不是允许您指定互斥体的列表,则必须以这种灵 active 来实现更高级别的操作,例如:

public static <T> boolean addIfNew(List<T> target, T value, Object mutex) {
    synchronized (mutex) {
        return !target.contains(value) && target.add(value);
    }
}

然后可以用作

List<String> synchedList=Collections.synchronizedList(new ArrayList<String>());
addIfNew(synchedList, "foo", synchedList);

这是有效的,因为 synchronizedList 返回的列表将使用自身作为互斥体。与 its documentation 比较:

强调我的

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

 List list = Collections.synchronizedList(new ArrayList());
     ...
 synchronized (list) {
     Iterator i = list.iterator(); // Must be in synchronized block
     while (i.hasNext())
         foo(i.next());
 }

该实现允许在内部使用不同的互斥对象的原因是您可以创建 sub lists并且同步列表的子列表将在支持列表实例上同步,而不是在其自身上同步(同样适用于Vector.subList)。因此,当您将子列表传递给高级方法时,将原始同步列表作为互斥体传递至关重要。

类似的事情也适用于 map 的 Collection View :

Collections.synchronizedMap :

It is imperative that the user manually synchronize on the returned map when iterating over any of its collection views:

Map m = Collections.synchronizedMap(new HashMap());
    ...
Set s = m.keySet();  // Needn't be in synchronized block
    ...
synchronized (m) {  // Synchronizing on m, not s!
    Iterator i = s.iterator(); // Must be in synchronized block
    while (i.hasNext())
        foo(i.next());
}
<小时/>

对此有一个简化。如果您确保对集合的所有访问都在您的方法中进行,则这些方法可能会同意任意互斥体,并且在该互斥体上一致同步的情况下是线程安全的。当然,集合本身不需要进行额外的同步,但这就是它的全部内容:

在实践中,您几乎找不到这些同步集合的任何有用场景。任何重要的操作都需要对集合进行多次访问,因此需要手动或更高级别的同步,这使得低级别同步变得过时。

人们很容易想到将同步集合传递给使用集合的任意方法,并自动获得线程安全性,而无需额外的同步,但由于只有当所述方法包含对集合的一次访问时,这才有效,因此您不会找到任何有用的现实生活方法。

因此,最重要的是,您始终必须确保您的代码线程安全并控制对集合的访问,因此永远不需要同步集合。

关于java - Util 创建一个在指定互斥体上同步的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29431930/

相关文章:

r - cbind 列表中的特定列(没有 dplyr 包)

python - 如何在 python 中创建 3x3 数独 block 列表

c++ - 修改 C++11 atomic bool 需要多少个时钟周期?

go 例程未从 channel 收集所有对象

java - 我可以在关闭Socket之前通过TCP发送数据吗?

java - 实现 useDelimiter 方法

java - Spring MVC - 什么是 url 路径信息?

java - JPA IdClass 混淆 - 这个想法实用吗?

c++ - 使用 <algorithm> sort 对自定义链表进行排序

mysql - 如何确保在mysql中只插入一行这些特定特征属性?