在我有一张地图并希望线程安全地公开其键集的情况下,这一定是相当普遍的情况:
public MyClass {
Map<String,String> map = // ...
public final Set<String> keys() {
// returns key set
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我的“地图”不是线程安全的,这是不安全的:
public final Set<String> keys() {
return map.keySet();
}
Run Code Online (Sandbox Code Playgroud)
两者都不是:
public final Set<String> keys() {
return Collections.unmodifiableSet(map.keySet());
}
Run Code Online (Sandbox Code Playgroud)
所以我需要创建一个副本,例如:
public final Set<String> keys() {
return new HashSet(map.keySet());
}
Run Code Online (Sandbox Code Playgroud)
但是,这似乎也不安全,因为该构造函数遍历参数的元素并将它们添加()。因此,在进行此复制时,可能会发生 ConcurrentModificationException。
那么:
public final Set<String> keys() {
synchronized(map) {
return new HashSet(map.keySet());
}
}
Run Code Online (Sandbox Code Playgroud)
似乎是解决方案。这看起来对吗?
该解决方案并不是特别有用,除非您计划在地图上使用它的任何地方进行同步。同步它并不会阻止其他人同时调用它的方法。它只会阻止他们也能够在其上同步。
如果您知道在有人可能进行迭代时需要并发放置和删除,那么最好的解决方案似乎确实是ConcurrentHashMap首先使用。如果该类提供的并发行为不是您所需要的,您可能只需要使用完全同步的 Map。
| 归档时间: |
|
| 查看次数: |
1367 次 |
| 最近记录: |