等待锁解锁,解锁后无需锁定

时间:2019-01-10 17:58:25

标签: java performance concurrency locking

很抱歉,如果标题是绕口令,但我说不出更好的话,因为那正是我想做的。

我有此方法/代码:

// 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,我怎么能得到这种行为?

0 个答案:

没有答案