Как разрешить одновременное чтение из синхронизированной структуры? - PullRequest
0 голосов
/ 03 сентября 2018

Предположим, у меня есть простая реализация кеша, подобная этой:

class Cache<Item> {
    private InternalStorage internalStorage;

    public synchronized Collection<Item> find(String query) {
        // find Items from internalStorage
    }

    public synchronized void add(Collection<Item> items) {
        // Add items to internalStorage
    }
}

Мне нужно предотвратить:

  1. Одновременная запись в internalStorage. т.е. нет одновременных звонков на add.
  2. Чтение происходит одновременно с записью. Т.е. нельзя одновременно звонить find и add.

Приведенная выше реализация удовлетворяет этим требованиям безопасности, однако при одновременных вызовах find нет никакого вреда, поскольку она не изменяет данные. Как я могу допустить это, при этом сохраняя структуру безопасности потока?

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

Расширить на Ответ Евгения . Вот как применить ReentrantReadWriteLock для достижения того, что мне нужно:

class Cache<Item> {
    final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

    private Map<String, Item> internalStorage;

    public Collection<Item> find(String query) {
        rwl.readLock().lock();
        try {
            // find Items from internalStorage
            // ...
            return result;
        } finally {
            rwl.readLock().unlock();
        }
    }

    public void add(Collection<Item> items) {
        rwl.writeLock().lock();
        try {
            // Add items to internalStorage
            // ...
        } finally {
            rwl.writeLock().unlock();
        }
    }
}
0 голосов
/ 03 сентября 2018

Кажется, что это довольно легко сделать, если бы вы использовали ReentrantReadWriteLock вместо synchronized здесь.

...