我遇到了以下问题(一个重要的限制 - 不能使用外部jar /库,只能使用常规安装的java原语):
类X的对象长期存储在sql DB中。为了性能起见,对象被缓存(需要编写。打算将它基于LinkedHashMap)。
get(key)
:
检查对象是否在缓存中而不在使用中 - 返回它。
如果对象正在使用 - 睡觉直到它可用。
如果对象不在缓存中 - 从DB中读取它。
putInCache(object)
:
更新缓存中的对象(如果它不在那里,添加它)。
如果缓存耗尽,它将触发缓存的saveToDB
操作并删除
从缓存中最近使用过的项目。
saveToDB(object)
:
将对象写入DB(不从缓存中删除)并标记对象并“未更改”。
有多个线程正在调用get
。线程可以更改从get
收到的对象(对象将被标记为“已更改”) - 完成后它将调用putInCache
。
有一个专用线程遍历缓存对象,当遇到“已更改”对象时,它将触发saveToDB
(对象将被标记为在进行数据库访问时使用)。
您如何建议确保线程安全?
基本上我正在寻找能够实现的正确Java类:
1. get
同步它对缓存中每个对象的访问权限。这样它就可以检查它是否在那里,如果是的话 - 如果它被使用或免费抓取。如果它被使用 - 它应该睡觉,直到它可用。
2.专用线程在调用saveToDB
时不应锁定缓存,但仍要确保检查所有缓存并且不会导致饥饿(缓存可能会在saveToDB
运行时更改)
只是为了澄清我只对锁定/同步解决方案感兴趣 - 可以假设缓存触发和数据库访问等内容。
答案 0 :(得分:0)
这是一种方法:
ExecutorService
来处理数据库请求; Future
s作为地图值; ConcurrentHashMap
作为地图实施。 Future
应该来自数据库;它将使用ExecutorService
。
当你需要对一个对象进行操作时,请同步这个将来作为对象的.get()
。
此外,谷歌搜索“Java并发实践”,并购买该书;)