我需要一些关于跟踪多线程场景的建议。我有一个xml文件,其中包含Web应用程序的一些配置数据。当用户访问网站时,基于用户访问的URL,将读取XML文件中的数据以找出附加到该用户请求的一些属性。为了提高从xml文件读取的性能,我使用了Ehcache。我正在缓存中缓存xml中的请求和相关配置。
所以,现在我面临的问题是。如果有人开始更新xml文件,我需要停止从缓存读取直到写入完成,并且一旦xml文件更新操作完成,我想清除缓存。然后将再次重建缓存。对于第二部分,我正在努力实现多线程来实现这一目标。文件更新可以通过两种方式完成,一种是用户使用notepad ++或其他工具直接编辑xml文件。另一种方式是使用相同的Web应用程序。
答案 0 :(得分:1)
您可以使用从共享BlockingQueue读取的工作线程池来刷新缓存;当用户完成编辑时,您将向队列发送一条消息,其中包含有关需要更新的kv对的信息。
public class RefreshRequest<K> {
public final K key;
public RefreshRequest(K key) { this.key = key; }
}
public final BlockingQueue<RefreshRequest<?>> requestQueue = new ArrayBlockingQueue<>(200);
public final int concurrency = 4;
public final ExecutorService executor = Executors.newFixedThreadPool(4);
for(int i = 0; i < concurrency; i++) {
executor.execute(new Runnable() {
public void run() {
try {
while(true) {
RefreshRequest<?> request = requestQueue.take();
// refresh key
}
} catch(InterruptedException e) {
return; // maybe log the exception as well
}
}
};
}
工作人员将消耗刷新缓存键的请求;您需要从最终确定更改为xml文件的代码中put
队列上的executor.shutdownNow()
个新请求。要终止工作人员,请致电while(true)
InterruptedException
<{1}}
至于当有人开始写入xml时如何停止从缓存中读取,你可以使用&#34;乐观的&#34;读。为每个xml文件分配版本号,并在写入文件时增加此版本。当您开始阅读时,将文件的版本存储在本地变量中。当读取完成时,将本地版本与文件的当前版本进行比较 - 如果它们匹配则返回读取值,如果它们不匹配则重复读取,包括将局部变量更新为当前版本文件版本。如果需要,你可以有一个&#34;无效&#34;版本(例如&#34;有效&#34;版本从0开始并在每次写入时递增,而&#34;无效&#34;版本为负-1) - 如果读者读取该文件是&#34 ;无效&#34;然后它暂停,例如5秒然后再次尝试。所以一种算法可能是
public Object read(K key) {
while(true) {
int version = versionCache.get(key);
if(version == -1) Thread.sleep(5000);
else {
Object returnVal = cache.get(key);
if(version == versionCache.get(key))
return returnVal;
}
}
}