具有不同超时的嵌套tryLock的ReentrantLock,实际的超时时间是多少?

时间:2019-06-07 08:45:35

标签: java multithreading locking

我正在尝试通过两个调用创建不公平的缓冲区

  1. 为缓冲区增加价值
  2. 清空缓冲区

清空队列的线程应具有更高的优先级 。

如果缓冲区已满,我会在内部调用empty方法以允许队列为空。

基本思想是,添加缓冲区的锁限于 addTimeout ,而空锁则为 emptyAddRatio * addTimeout ,因此添加将具有更高的优先级(假设为我有更多的补充,然后再清空)。

public class EmptyPriorityBuffer {
private ReentrantLock lock = new ReentrantLock(true);
private long addTimeout = 10;
private long emptyAddRatio = 5;
private int maxSize = 1000;
private LinkedBlockingDeque<Object> buffer = new LinkedBlockingDeque<>(maxSize);

public List<Object> empty() {
    try {
        lock.tryLock(addTimeout * emptyAddRatio, TimeUnit.MILLISECONDS);
        ArrayList<Object> result = new ArrayList<>();
        buffer.drainTo(result);
        return result;
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
    return Collections.emptyList();
}

public void add(Object object) {
    try {
        lock.tryLock(addTimeout, TimeUnit.MILLISECONDS);
        if (!buffer.offer(object)) {
            empty();
            buffer.offer(object);
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}

我的问题: 如果缓冲区已满,将会发生什么情况。
当前已获取要使用addtimeout锁定的线程,现在它要求使用 emptyAddRatio * addTimeout 的嵌套锁大于 addTimeout
emptyAddRatio * addTimeout addTimeout 之后,线程会中断吗?

1 个答案:

答案 0 :(得分:1)

可重入的情况下的timeout参数不会生效,因为您已经拥有该锁。也就是说,对add的调用已经获得了锁(并且可能必须等待最多addTimeout毫秒。任何进一步的尝试来获取相同的锁都将立即成功。

但是请注意,您需要在方法lock.tryLockempty中都检查add的返回值,以确定获取锁是实际成功还是超时。在后一种情况下,您可能想要中止而不是继续。