我在我的代码中有一个静态的HashSet对象引用,它必须在给定的方法正在运行之前不允许所有写入请求(它仅将哈希集用于读取目的)。我已阅读线程基础知识,但尚不清楚如何继续这样做。在Java中锁定哈希集合
任何人都可以帮我吗?
我在我的代码中有一个静态的HashSet对象引用,它必须在给定的方法正在运行之前不允许所有写入请求(它仅将哈希集用于读取目的)。我已阅读线程基础知识,但尚不清楚如何继续这样做。在Java中锁定哈希集合
任何人都可以帮我吗?
您提到您已阅读线程基础知识,因此我假设您有一个多线程应用程序,您有多个阅读器和/或作者。您可以使用读写锁来限制对该集合的访问。当给定的方法执行时,它锁定读取锁定,允许其他人读取,但不写入。只要您使用下面的putInSet
方法(或类似方法)编写代码,就可以要求写入锁写入。然后在读锁被保持时,该组不能写入。
private final Set<Object> mySet = new HashSet<Object>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public void methodThatRunsAndAllowsReadOnly() {
lock.readLock().lock();
try {
// method body here
}
finally {
lock.readLock().unlock();
}
}
public void putInSet(Object o) {
lock.writeLock().lock();
try {
mySet.add(o);
}
finally {
lock.writeLock().unlock();
}
}
+1使用读写锁。 – 2010-10-11 22:28:02
我正在查看ReentrantReadWriteLock的javadocs,它说,如果不首先释放读取锁定,则无法升级到写入锁定。您可能需要释放读取锁定作为putInSet()中的第一行,然后在释放写入锁定之前重新获取finally中的读取锁定。 – InverseFalcon 2011-09-16 23:56:00
您可以使用Collections.unmodifiableSet
创建该设备的只读视图。只需将此视图传递给不需要写入集合的所有人即可。 (对于任何试图修改此视图的人,都将引发UnsupportedOperationException
)。
这是一个有趣的问题,通常情况下是相反的。
如果你想要一个不变的映射,直到某个魔术方法告诉应用程序的其余部分它可以,那么可以使用Collections.unmodifiableMap()
在初始化后创建映射的不可变副本。
当magic方法运行时,它可以用一个可修改的副本再次替换地图。
Map myMap;
public MyClass(Map myMap) {
this.myMap = Collections.unmodifiableMap(myMap);
}
synchronized public void releaseMyMap() {
myMap = new HashMap(myMap);
}
您可以从一个集合扩展并提供您自己的基于锁定的实现(添加)读取和写入集合。
这将确保无论何时一个线程正在读取(在获取锁定之后),其他线程都不能写入它。
不完全确定问题所在,但如果您只是试图避免使用HashSet访问并发问题,可能值得看看ConcurrentSkipListSet。大部分操作需要log(n)时间,但不需要同步,并且不会在插入,删除和访问操作时阻塞。在整体上可能会给你更好的表现。
什么意思是不允许的?块?抛出异常? – 2010-10-11 17:21:39
拼写检查:我想不是“在给定方法运行之前不允许所有写请求”应该是“在给定方法运行时不允许所有写请求”? – 2010-10-11 17:29:17
此外,使用示例代码发布您的问题会很有帮助 - 使您的问题更清晰易懂,并且更易于回答。 – 2010-10-11 17:30:10