我有一个这样的用例。我的方法之一采用列表作为参数。当且仅当至少一个对象已被其他线程锁定时,我才需要保护关键部分。如何使用java.util.concurrent包实现?我可以想到简单的基于哈希表的解决方案, 类似的东西
class ContainsCriticalSections {
HashTable<SomeObject, Thread> map; //shared by multiple threads
someCriticalMethod(List<SomeObject> objects) {
acquireLocks(objects);
//do critical task
releaseLocks(objects);
}
synchronized acquireLock(List<SomeObject> objects) {
bool canLock = false;
while (!canLock) {
for (SomeObject obj : objects) {
if (!map.contains(obj)) {
canLock = true;
}
else if(map.get(obj).equals(Thread.currentThread())) {// ensuring re-entrace
canLock = true;
}
else {
canLock = false;
}
}
if (!canLock) {
wait();
}
}
for (SomeObject obj : objects) {
map.put(obj, Thread.currentThread());
}
}
synchronized releaseLock(List<SomeObject> objects) {
for (SomeObject obj : objects) {
map.reomve(obj);
}
notify();
}
}
因此,在上述情况下,如果 A、B、C 和 D、E、F 的两次调用不会阻塞。但是,A、B、C 和 A、E、F 会阻塞。
但是,我强烈认为这里会有一些既定的范例(使用 java.util.Concurrent)。
最佳答案
我怀疑您正在寻找ReadWriteLock
。请参阅ReentrantReadWriteLock举个例子。
ReadWrite
锁允许多个并发 Read
锁,但任何获取 Write
锁的尝试都将被阻塞,直到所有锁(Read
或 Write
)已发布。
因此,采用 List
的方法应该请求 Write
锁,而所有其他方法都请求 Read
锁。
关于Java 避免在不相交集合的情况下锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14748231/