Ehcache多线程场景

时间:2016-05-23 03:50:19

标签: java multithreading caching ehcache

我需要一些关于跟踪多线程场景的建议。我有一个xml文件,其中包含Web应用程序的一些配置数据。当用户访问网站时,基于用户访问的URL,将读取XML文件中的数据以找出附加到该用户请求的一些属性。为了提高从xml文件读取的性能,我使用了Ehcache。我正在缓存中缓存xml中的请求和相关配置。

所以,现在我面临的问题是。如果有人开始更新xml文件,我需要停止从缓存读取直到写入完成,并且一旦xml​​文件更新操作完成,我想清除缓存。然后将再次重建缓存。对于第二部分,我正在努力实现多线程来实现这一目标。文件更新可以通过两种方式完成,一种是用户使用notepad ++或其他工具直接编辑xml文件。另一种方式是使用相同的Web应用程序。

1 个答案:

答案 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;
        }
    }
}