作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
这一定是相当常见的情况,我有一个 map 并希望以线程安全的方式公开其键集:
public MyClass {
Map<String,String> map = // ...
public final Set<String> keys() {
// returns key set
}
}
现在,如果我的“ map ”不是线程安全的,那么这是不安全的:
public final Set<String> keys() {
return map.keySet();
}
也不是:
public final Set<String> keys() {
return Collections.unmodifiableSet(map.keySet());
}
所以我需要创建一个副本,例如:
public final Set<String> keys() {
return new HashSet(map.keySet());
}
但是,这似乎也不安全,因为该构造函数遍历参数的元素并添加()它们。因此,在进行此复制时,可能会发生 ConcurrentModificationException。
然后:
public final Set<String> keys() {
synchronized(map) {
return new HashSet(map.keySet());
}
}
似乎是解决方案。这看起来对吗?
最佳答案
该解决方案并不是特别有用,除非您还计划在 map 上使用它的任何地方进行同步。同步它不会阻止其他人同时调用它的方法。它只会阻止他们也能够同步。
最好的解决方案似乎是首先使用 ConcurrentHashMap
如果您知道您需要并发放置和删除,而有人可能正在迭代。如果类提供的并发行为不是您所需要的,您可能只需要使用完全同步的 Map。
关于java - 公开 keySet() 的线程安全方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4709567/
我是一名优秀的程序员,十分优秀!