解决以下问题的正确方法是什么?
编写一个逻辑,其中 100 个读取器(Servlet 请求)或一个写入器(Servlet 请求)可以同时访问映射(缓存)中一个键的关键部分。如果在这种情况下写入器进入画面,所有读取器都应该停止进度,并且一旦写入器完成关键部分处理(重新填充同一键的缓存元素),就应该重新启动。
我实现了一个类似这个问题的解决方案,其中一个 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 个许可,如果在这种情况下写入线程进入图片,我消耗了所有剩余的许可(drainPermits)并让所有许可免费所有读取器和写入器线程都在等待队列中。但它导致作家挨饿。
我认为使用 ConcurrentHashMap 可以解决的其他事情?由于 ConcurrentHashMap 在内部具有基于键的锁定(段)。