使用线程

时间:2018-03-24 17:46:17

标签: java concurrency synchronization reentrantlock

作为线程之间的同步方法,在Java中我们可以使用ReentrantLock类。它有一个名为tryLock()的方法,如果它注意到还没有获得一个线程,它允许线程不等待。当它返回一个布尔值时,它可以与if语句结合使线程做其他事情,如果它们无法获取锁定,类似于:

if (lock.tryLock()) {
    // Do things inside the lock
    lock.unlock();
} else {
    // The lock was occupied, do other things
}

直到那里,事情才会发生。但是,假设我们有两个(或更多)锁,我们希望在进入临界区之前获取它们。在某些特定情况下,第一个锁可用,但不是第二个锁。为了使这个场景正常工作,我提出了一些可供选择的选项。请注意,我更担心锁的解锁,而不是锁定:

// Option 1
if (lock1.tryLock() && lock2.tryLock()) {
    // Congratulations! You are inside both locks
} else {
    // How to know if you got a lock, and if so, which one?
    // You will need to "blindly" unlock both
    try {
        lock1.unlock();
        lock2.unlock();
    } catch (IllegalStateMonitorException e) {
        // Thrown when you unlock a lock which is not yours
    }
}

在我的实现中,第一个选项基本上忽略了一个异常,这可能会在执行的某个时刻引起问题。

// Option 2
if (lock1.tryLock()) {
    if (lock2.tryLock()) {
        // Congratulations! You are inside both locks
        // Do things
        lock2.unlock();
    }
    lock1.unlock();
}

这第二个选项利用了这样一个事实,即可能没有获得第二个锁,但第一个锁得到了。我觉得这更有效率和直观。

您认为哪个选项最好?您对此主题有更好的实施吗?

1 个答案:

答案 0 :(得分:1)

只使用第二种变体。第一个会引起问题,例如当第二个锁由另一个线程持有时。它也不会以正确(反向)顺序解锁。