java - Ehcache多线程场景

标签 java multithreading caching ehcache

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

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

最佳答案

您可以使用从共享 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 文件更改的代码的新请求放入队列中。要终止工作线程,请调用 executor.shutdownNow() ,它将通过 InterruptedException

打破 while(true) 循环 <小时/>

至于当有人开始写入 xml 时如何停止从缓存读取,您可以通过“乐观”读取来实现。为每个 xml 文件分配一个版本号,并在写入文件时递增此版本。当您开始读取时,将文件的版本存储在本地变量中。读取完成后,将本地版本与文件的当前版本进行比较 - 如果它们匹配,则返回读取值,如果不匹配,则重复读取,包括将本地变量更新为当前的文件版本。如果需要,您可以有一个“无效”版本(例如,“有效”版本从 0 开始,每次写入时递增,而“无效”版本为负 1) - 如果读者读取到该文件是“无效”然后它暂停例如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;
        }
    }
}

关于java - Ehcache多线程场景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37382395/

相关文章:

go - Memcached Ping()在无效服务器上未返回错误

java - 我可以使用字符串作为 Id 吗?

java - 如何将 JTable 添加到从 JScrollPane 扩展的类中?

java - 在 RecyclerView 滚动监听器中实现单击监听器

java - 在 Java 中使用 ThreadPoolExecutor 实现动态文件传输 Controller

java - 通过CompletableFuture并行执行一些线程,并串行执行一些线程

caching - Apollo GraphQl 使用react。如何清除所有变量组合的查询缓存?

java - 测试方法是否以同步方式运行

java - java中的并发队列消耗之谜

caching - Node.js/快速缓存