很抱歉,如果标题是绕口令,但我说不出更好的话,因为那正是我想做的。
我有此方法/代码:
// No need fairness (false) the first to get it is good to go
private final Lock TEST = new ReentrantLock(false)
public methodCalledByMultipleThreads() {
// 1st code section - no concurrency problems
// regardless of what happen in section 2 a thread that just called
// this function should always be able to run section 1
// 2nd code section begin
if (rare_condition && TEST.tryLocking()) {
// check again to avoid limit cases where "rare_condition" value
// is invalidated by another thread (who ran "important stuffs")
// and just released/unlock TEST with "TEST.unlock();"
if (check_rare_condition_again) {
// ##### do "important stuffs" #####
// release lock
TEST.unlock();
}
}
TEST.waitUntilUnlocked(); // this is what I actually would like to do
// ##### do other stuffs #####
}
当然,当等待结束时,“ waitUntilUnlocked”不应锁定“ TEST”。我试图通过恶意使用Semaphore来获得所需的行为...这确实很糟糕,没有为此设计信号灯,并且在这种情况下还会造成开销(内部许可计数不计算任何内容……只是花式锁):
private final Lock TEST = new ReentrantLock(false)
// absurd high value (Integer.MAX_VALUE) for permits, to allow "virtually"
// infinite threads to works with this code
private final Semaphore SEM = new Semaphore(Integer.MAX_VALUE, true);
public methodCalledByMultipleThreads() {
// 1st code section
// 2nd code section begin
if (rare_condition && TEST.tryLocking()) {
if (check_rare_condition_again) {
// waits to gets all permits
SEM.acquireUninterruptibly(Integer.MAX_VALUE);
// ##### do important stuffs #####
// release all permits
SEM.release(Integer.MAX_VALUE);
// release lock
TEST.unlock();
}
}
// ask one permit
SEM.acquireUninterruptibly();
// ##### do other stuffs #####
// release one permit
SEM.release();
}
上述解决方案是“可行的”(通过运气实现实际的代码速度已经足够慢,暂时不会导致任何边缘情况...),但是从理论上讲是错误的,因为“ SEM.release(Integer.MAX_VALUE);”和“ TEST.unlock();”应该是一回事。
如果没有这种丑陋的hack,我怎么能得到这种行为?