ReentrantLock с вложенным tryLock с разными тайм-аутами, каким будет фактический тайм-аут? - PullRequest
1 голос
/ 07 июня 2019

Я пытаюсь создать недобросовестный буфер с двумя вызовами

  1. Добавить значение в буфер
  2. Очистить буфер

Потоки, которые очищаюточередь должна иметь более высокий приоритет те потоки, которые добавляют в очередь.

В случае, если буфер заполнен, я вызываю пустой метод внутри, чтобы позволить очереди опустошиться.

Основная идея заключается в том, что блокировки для буфера добавления ограничены addTimeout , а блокировки для пустого - emptyAddRatio * addTimeout , поэтому add будет иметь более высокий приоритет (предполагается, что у меня есть больше дополненийзатем пусто).

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 witch больше чем addTimeout .
Будет ли прерываться поток после emptyAddRatio * addTimeout или addTimeout ?

1 Ответ

1 голос
/ 07 июня 2019

Аргумент тайм-аута в случае повторного входа не будет иметь эффекта, поскольку у вас уже есть блокировка. То есть, вызов add уже получил блокировку (и, возможно, ему пришлось ждать макс. addTimeout миллисекунды. Любая дальнейшая попытка получить такую ​​же блокировку будет успешной немедленно.

Обратите внимание, однако, что вам нужно проверить возвращаемое значение lock.tryLock в обоих методах empty и add, чтобы определить, действительно ли получение блокировки действительно прошло или истекло время ожидания. В последнем случае вы, скорее всего, захотите прервать, а не идти вперед.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...