Делегирование ReentrantReadWriteLock в родительский поток - PullRequest
1 голос
/ 02 марта 2012

Я хочу отправить задачи в ForkJoinPool или ParallelArray из потока, содержащего блокировку записи. Доступ к нашей модели домена защищен проверками того, что текущий поток удерживает соответствующую блокировку. Чтобы позволить работникам FJ выполнять над ним задачи (только чтение, например, запросы), им необходимо делегировать проверки доступа потоку, который их породил.

Я вложил в класс ForkJoinWorkerThread ссылку на нить порождения. Затем я помещаю в подкласс ReentrantReadWriteLock и переопределяю isWriteLockedByCurrentThread, чтобы выполнить обычную проверку, и возвращаюсь к проверке того, что, если поток является экземпляром делегирующего FJWorker, что поток делегата (родительский) является владельцем блокировки, используя ReentrantReadWriteLock # GetOwner ()

public class DelegateAwareReentrantReadWriteLock extends ReentrantReadWriteLock {
    @Override
    public boolean isWriteLockedByCurrentThread() {
        return super.isWriteLockedByCurrentThread() || isWriteLockedByDelegateThread();
    }

    private boolean isWriteLockedByDelegateThread() {
        final Thread currentThread = Thread.currentThread();
        if (currentThread instanceof FJAccessDelegatingWorker) {
            final Thread delegate = ((FJAccessDelegatingWorker) currentThread).getDelegate();
            return delegate.equals(getOwner());
        }
        return false;
    }
}

Однако документация для getOwner () гласит следующее:

Когда этот метод вызывается поток, который не является владельцем, возвращаемое значение отражает наилучшее приближение текущего состояния блокировки. Например, владелец может на мгновение быть нулевым, даже если есть потоки пытаются получить блокировку, но еще не сделали этого.

Я хотел бы понять, что это означает, что если я отправил задачи в потоке, которому уже был предоставлен доступ, этот метод правильно вернет ссылку на него. К сожалению, это даже не подразумевается.

Если я не могу использовать этот метод, какие существуют альтернативы для такого рода делегирования?

Спасибо.

1 Ответ

0 голосов
/ 02 марта 2012

Я полагаю, что детали реализации getOwner () таковы, что, если между потоком, который установил блокировку записи, и потоком, запрашивающим владельца, существует отношение «произойдет до», то он будет иметь детерминированное поведение, обеспечивающее правильного владельцавозвращаетсяЯ не проверял реализацию, но мне кажется, что это то, на что намекают комментарии, и охватывают основу, по которой поведение может быть недетерминированным во время получения блокировки.

Однако это можетбудет проще, если вы сможете понизить блокировку записи и избежать всех проверок делегирования для начала (с тех пор каждый поток может иметь собственную блокировку чтения).Возможно, также возможно использовать две отдельные блокировки, скажем, внешнюю и внутреннюю блокировку, где внутренняя блокировка не сохраняется для записи в этом случае?

Редактирование: реализация getOwner () вызывает getState (), которыйвыполняет чтение переменной volatile, и этого должно быть достаточно, чтобы гарантировать, что getOwner () всегда будет возвращать ваш родительский поток, если он удерживает блокировку записи.

...