Проблема параллелизма Java с запросами сервлета - PullRequest
0 голосов
/ 02 июля 2019

Как правильно решить следующую проблему?

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

Я реализовал одно из решений , как в этом вопросе , где один экземпляр класса Resource будет связан с одним ключом.

class Resource {
  private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
  private final Lock rlock = lock.readLock();
  private final Lock wlock = lock.writeLock();

  void read() { ... /* caller has to hold the read lock */ ... }
  void write() { ... /* caller has to hold the write lock */ ... }

  Lock readLock() { return rlock; }
  Lock writeLock() { return wlock; }
}

Ранее я реализовал простую логику, используя семафор, где я связал один экземпляр семафора с одним ключом и использовал 100 разрешений для одного и того же, и если поток писателя входит в изображение, в этом случае я использовал все оставшиеся разрешения(illPermits) и разрешить всем разрешать освобождение всех читателей и помещать поток писателя в очередь ожидания.Но это приводит к голоду для писателя.

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

1 Ответ

0 голосов
/ 02 июля 2019

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

class Resource {
  private Cache<Key, Value> yourcache;
  private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
  private final Lock rlock = lock.readLock();
  private final Lock wlock = lock.writeLock();

  Value read(Key key) { try {
rlock.lock();
return yourcache.get(key)
} finally {
rlock.unlock();
}
}
  void write(Key key) { ... /* similar pattern to above */ ... }

  Lock readLock() { return rlock; } //don't expose these at all!
  Lock writeLock() { return wlock; }//don't expose these at all!
}
...