我有一个平面文件,其中包含设备标识符列表。当我的基于Java / tomcat的应用程序从特定设备接收请求时,它根据文件中设备标识符的存在来决定业务逻辑(即使设备存在,设备标识符也可能不存在于文件中)。
还有用例为了使(多线程)应用程序更快,而不是每次读/写操作直接访问文件,我需要将内容存储在内存中。
以下是要求(摘要):
在应用程序启动期间读取内存(缓存)中文件的内容。
以多线程方式从缓存中读取内容。如果内容不在缓存中,则不应该在文件中,反之亦然(单点)。
当有新设备标识时,需要更新缓存和文件。
当需要删除设备标识时,需要更新缓存和文件。
该应用程序以Java格式运行。
有哪些选择?我最初想过使用gauva缓存。但是,我不确定它是否支持将其内容写回源文件。 即使是简单的属性文件(java.util.properties)也应该这样做。但是,不确定这是否适合高度多线程的环境。
感谢您的建议。
答案 0 :(得分:4)
与大多数缓存一样,Guava的主要用于以直读方式使用。目的是更新权威数据源,然后使缓存失效。缓存不支持直写或后写,并且在顶部添加这些功能可能会导致微妙的竞争条件。
Java 8重写Caffeine支持通过ConcurrentHashMap's原子计算方法添加该功能。直写使用更新数据源的compute
,如果成功,则将值存储在缓存中。后写使用compute
方法,该方法异步更新数据源并乐观地将值存储在缓存中。在这两种情况下,如果条目在计算期间存在,则读取是非阻塞的,并且在更新完成之前接收旧值。
对于内存缓存的常见用法,直写和后写都不是很好的方法。在适当的时候,他们需要更周到的关怀和定制,因此提供通用支持被认为会导致开发人员误入歧途,并提供很少的好处。重写提供了使功能成为可能的机会,而无需直接推广。
答案 1 :(得分:1)
作为使用HashSet作为扩展点的起点。
class DeviceCache extends HashSet<Device> {
boolean add(Device d) {
boolean rv = super.add(d);
if (!rv) {
... Add the device to the file.
}
return rv;
}
remove(Device d) {
boolean rv = super.remove(d);
if (rv) {
... Remove the device from the file
}
return fv;
}
}
远未完成。有什么想法吗?