我有一个系统可以缓存启动时SOAP调用的微小/简单结果
我需要实例能够在启动时重新加载缓存(如果SOAP服务已经死亡)并且还使用此缓存文件处理多个实例的可能性
我选择使用java.util.prefs
但是Java的内置自动同步线程间歇性地失败(1%的时间使用默认的JVM 30s支持存储同步)转储以下异常:
Jan 8, 2010 12:30:07 PM java.util.prefs.FileSystemPreferences syncWorld
WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: Couldn't get file lock.
我怀疑是this bug,但这已在1.5(tiger-b40)中修复,此框中的java 5为“1.5.0_16-b02”。
我现在怀疑这可能是因为我们有多个JVM共享这个Backing Store,尽管在我们的其他机器上似乎没有这种情况。
任何人都可以证实吗? 有什么风险,如果有的话?
如果我的方法存在缺陷,我应该将其作为替代方案使用?
答案 0 :(得分:10)
“我现在怀疑这可能是因为我们有多个JVM共享此Backing Store”
绝对可能是这种情况! 如果两个JVM尝试同时锁定文件,那么这就是你所看到的。
具体细节取决于锁的类型,操作系统和文件系统。
您可能想尝试在try / catch块中包装导致此操作的操作,然后在失败时重试该操作。
答案 1 :(得分:1)
我遇到了与码头相同的问题。我发现以下问题解决了这个问题。
将.systemPrefs
添加到您的JRE目录,并提供对正在运行正在抱怨的流程的用户的访问权限。
完成后,转到Jetty目录并打开start.ini
文件
- Djava.util.prefs.userRoot={user's home directory}
- Djava.util.prefs.systemRoot={user's home directory}
完成添加这些行后,我重新启动了jetty,发现错误消失了。
答案 2 :(得分:0)
不使用Preferences,只需使用任何可序列化的Map并创建一个非常简单的缓存类,它将序列化和反序列化为随机生成的临时文件名(在首次初始化时生成的文件名)。由于它只是一个缓存,因此您可以捕获任何异常并在发生异常时将缓存重置回其初始状态,因此它将从原始数据源(在您的情况下为SOAP服务)中重新获取。因此,如果您不想,不需要担心serialVersionUID或任何兼容性内容。