Заблокировать хешсет в Java - PullRequest
1 голос
/ 11 октября 2010

У меня есть статический HashSet ссылок на объекты в моем коде, который должен запрещать все запросы на запись, пока не будет запущен данный метод (который использует хэш-набор только для целей чтения). Я прочитал основы темы, но пока не ясно, как это сделать.

Может кто-нибудь помочь мне?

Ответы [ 5 ]

9 голосов
/ 11 октября 2010

Вы упомянули, что прочитали основы Thread, поэтому я предполагаю, что у вас есть многопоточное приложение, в котором есть несколько читателей и / или пишущих для набора.Вы можете использовать блокировку чтения-записи, чтобы ограничить доступ к коллекции.Когда данный метод выполняется, он блокирует блокировку чтения, которая позволяет другим читать, но не писать.Пока вы пишете с использованием метода putInSet (или чего-то подобного) ниже, вы можете требовать блокировки записи для записи.Тогда набор не может быть записан, пока удерживается блокировка чтения.

private final Set<Object> mySet = new HashSet<Object>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public void methodThatRunsAndAllowsReadOnly() {
    lock.readLock().lock();
    try {
        // method body here
    }
    finally {
       lock.readLock().unlock();
    }
}

public void putInSet(Object o) {
    lock.writeLock().lock();
    try {
        mySet.add(o);
    }
    finally {
       lock.writeLock().unlock();
    }
 }
6 голосов
/ 11 октября 2010

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

1 голос
/ 11 октября 2010

Это интересный вопрос, обычно это наоборот.

Если вы хотите неизменную карту, пока какой-нибудь магический метод не сообщит остальной части приложения, что все в порядке, вы можете использовать Collections.unmodifiableMap() для создания неизменяемой копии вашей карты после инициализации.

Когда магический метод запускается, он может снова заменить карту изменяемой копией.

Map myMap;

public MyClass(Map myMap) {
    this.myMap = Collections.unmodifiableMap(myMap);
}

synchronized public void releaseMyMap() {
    myMap = new HashMap(myMap);
}
0 голосов
/ 12 октября 2010

Не знаю точно, в чем проблема, но если вы просто пытаетесь избежать проблем параллелизма с доступом к HashSet, возможно, стоит взглянуть на ConcurrentSkipListSet. Для большинства операций требуется время log (n), но оно не требует синхронизации и не блокирует операции вставки, удаления и доступа. В целом, это может дать вам лучшую производительность.

0 голосов
/ 11 октября 2010

Вы можете расширять набор и предоставлять собственную реализацию на основе блокировок (добавления) для чтения и записи в набор.

Это гарантирует, что всякий раз, когда поток читает (после получения блокировки), никакой другой поток не может писать в него.

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