我对多线程环境有些新鲜感,我想为以下情况提出最佳解决方案:
我每天早上从数据库中读取数据,并将数据存储在单个对象中的HashMap中.我有一个setter方法,只有当日内DB更改发生时才会调用(每天会发生0-2次).
我也有一个getter返回地图中的一个元素,这种方法每天被调用数百次.
我担心在排空和重新创建HashMap时调用getter的情况,因此尝试在空/格式列表中找到一个元素.如果我使这些方法同步,它可以防止两个读卡器同时访问getter,这可能是一个性能瓶颈.我不想太多的性能打击,因为写入不经常发生.如果我使用ReentrantReadWriteLock,这会在任何调用getter的情况下强制一个队列,直到写锁定被释放吗?是否允许多位读者同时访问吸气剂?一次只能执行一位作家吗?
编码这只是一个问题…
private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); private final Lock read = readWriteLock.readLock(); private final Lock write = readWriteLock.writeLock(); public HashMap getter(String a) { read.lock(); try { return myStuff_.get(a); } finally { read.unlock(); } } public void setter() { write.lock(); try { myStuff_ = // my logic } finally { write.unlock(); } }
解决方法
实现此功能的另一种方法(不使用锁定)是写时复制模式.当你不经常写的时候,效果很好.这个想法是复制和替换字段本身.它可能如下所示:
private volatile Map<String,HashMap> myStuff_ = new HashMap<String,HashMap>(); public HashMap getter(String a) { return myStuff_.get(a); } public synchronized void setter() { // create a copy from the original Map<String,HashMap> copy = new HashMap<String,HashMap>(myStuff_); // populate the copy // replace copy with the original myStuff_ = copy; }
这样读者就完全并发了,而且他们付出的唯一的惩罚就是对myStuff_(这是非常少的)的动态阅读.作家同步,以确保互相排斥.