我有十个通用函数,它们都在我的框架中经常运行。其中两个函数是A类型,另外八个函数是B类。我希望能够同时运行类型A函数,但不允许在类型A函数运行时运行类型B函数。同样,如果B类函数正在运行,我也不希望允许任何类型A函数运行。如果其中一个已经在运行,我也不希望任何其他类型的B运行。
除了使用ReentrantReadWriteLock之外,有没有更好的方法来实现它(特别是Java),类型A周围的读锁定和类型B周围的写锁定?
ReentrantReadWriteLock用于在大多数时间需要读取器锁定时,需要编写器锁定"偶尔使用#34;。但是,就我而言,所有函数都是一直使用的,这意味着函数都以相同的频率被调用。无论我是否使ReentrantReadWriteLock公平或不公平,我都看到我的系统中存在大量争用锁。
答案 0 :(得分:0)
ReentrantReadWriteLock用于在大多数时间需要读取器锁定时,需要编写器锁定"偶尔使用#34;。
我不知道你有什么想法。在许多地方使用ReentrantReadWriteLock
来处理完全您概述的情况。它被设计为高性能且(当然)可重入,并且您可能通过手动编码拼凑的任何解决方案很可能不会表现得很好。
但是,在我的情况下,所有函数都一直在使用,这意味着函数都以相同的频率被调用。
这应该没问题。你应该阅读ReentrantReadWriteLock
javadocs周围"公平"的细则。但是A和B的任何频率都将由锁井处理。
总结文档,在" fair"模式,如果B任务进入写锁定,它将阻止在后面的一组已经等待的A任务。如果A任务进入锁定状态,则仅当没有B任务已经在等待时才允许它运行。 "不正当"模式将允许A任务运行并且如果它们连续出现可能会饿死B任务,但可能"通常具有比公平锁定更高的吞吐量"。
我会坚持"公平"政策,除非您有特殊理由不这样做。
无论我使ReentrantReadWriteLock公平还是不公平,我都看到系统中存在大量争用锁。
我认为这是可以预料的。无论你提出什么解决方案,如果你有A和B任务以下降频率执行,你将获得锁争用。也许如果您编辑了问题并提供了有关您认为争用意外的原因的更多详细信息,我们可以提供更好的答案。
我希望能够同时运行A类函数,但不允许在A类函数运行时运行B类函数。
所以A任务会使用ReentrantReadWriteLock
的读取部分:
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private final Lock readLock = readWriteLock.readLock();
private final Lock writeLock = readWriteLock.writeLock();
...
private void functionA() {
readLock.lock();
try {
// do the A processing here ...
} finally {
readLock.unlock();
}
}
如果B类功能正在运行,我不希望允许任何类型A功能运行。如果其中一个已经在运行,我也不希望任何其他类型的B运行。
所以B任务会使用锁的写部分:
private void functionB() {
writeLock.lock();
try {
// do the B processing here ...
} finally {
writeLock.unlock();
}
}