是否有一些实用程序在指定的互斥锁上创建同步列表?喜欢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 :
<小时/>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/