当前位置: 首页 > 面试题库 >

HashMap缓存中的同步

钦耀
2023-03-14
问题内容

我有一个Web应用程序,人们需要资源。使用同步哈希映射来缓存此资源以提高效率。这里的问题是,当两个不同的请求同时到达同一未缓存资源时:检索资源的操作占用大量内存,因此我想避免为同一资源多次调用它。

有人可以告诉我以下代码段是否存在任何潜在问题吗?提前致谢。

private Map<String, Resource> resources = Collections.synchronizedMap(new HashMap<String, Resource>());

public void request(String name) {

  Resource resource = resources.get(name);

  if (resource == null) {
    synchronized(this) {
      if (resources.get(name) == null) {
        resource = veryCostlyOperation(name); // This should only be invoked once per resource...
        resources.put(resource);
      } else {
        resource = resources.get(name);
      }
    }
  }

  ...

}

问题答案:

一个可能的问题是,您通过veryCostlyOperation()在一个synchronized块内执行来创建不必要的竞争,因此许多线程无法同时检索其(独立)资源。这可以通过使用Future<Resource>map的值来解决:

Map<String, Future<Resource>> map = new ConcurrentHashMap<String, Future<Resource>>();    
...
Future<Resource> r = map.get(name);
if (r == null) {
    FutureTask task = null;
    synchronized (lock) {
        r = map.get(name);
        if (r == null) {
            task = new FutureTask(new Callable<Resource>() {
                public Resource call() {
                    return veryCostlyOperation(name);
                }
            });
            r = task;
            map.put(name, r);
        }
    }
    if (task != null) task.run(); // Retrieve the resource
}

return r.get(); // Wait while other thread is retrieving the resource if necessary


 类似资料:
  • 本文向大家介绍HTML缓存中单个URL有几个不同的缓存?,包括了HTML缓存中单个URL有几个不同的缓存?的使用技巧和注意事项,需要的朋友参考一下 您需要在列表的CACHE部分中提供的所有资源上使用远期到期日期。此外,在CACHE部分的每个文件中添加时间戳后缀- 当服务器上的任何文件更改时,要更改时间戳,您需要更新列表。下一次下载了带有修改后的时间戳的文件。

  • 本文向大家介绍java使用hashMap缓存保存数据的方法,包括了java使用hashMap缓存保存数据的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了java使用hashMap缓存保存数据的方法。分享给大家供大家参考,具体如下: 更多关于java算法相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇

  • 我有一个每10分钟运行一次的cron作业,并更新内容类型和x-amz-meta。但从昨天开始,似乎在cron作业运行之后,亚马逊并没有恢复所做的更改(刷新他的缓存)。 我甚至手动进行了更改,但没有更改... 上载视频时,它有一个应用程序/x-mp4内容类型,cron作业将其更改为视频/mp4。 虽然S3的内容类型正确,但cloudfront显示的是应用程序/x-mp4(旧的内容类型)。。。。 cr

  • 如果缓存通道[]而不是缓存ChannelHandlerContext,会有什么不同吗? 以下是实现的步骤和问题: > Netty服务器处理程序从客户端接收消息 因为有其他正在运行的线程来处理用户数据,所以我们需要将此请求放到队列中,并让辅助处理 服务器和客户端之间的多消息交换需要使用相同的连接 每当消息准备好从辅助线程发送到客户端时,最好使用缓存在HashMap中的通道 final Channel

  • 我们可以通过下面的简单算法实现该目的: 检查本地缓存的键(key); 如果本地缓存存在该键,则返回它的值; 如果本地缓存不存在该键,则尝试在分布式缓存中找; 如果分布式缓存存在该键,则返回它的值并把它添加到本地缓存; 如果分布式缓存不存在该键,则从数据库中获取,并添加到本地和分布式缓存,最后返回该值。 当在本地缓存服务器中缓存一些信息时,使用这种方式,它还将信息缓存到分布式缓存,但这一次,如果其他

  • 问题内容: 在的实现细节中,我可以阅读: 如果我有恒常的能力,而我的班级没有实现,它将如何打破束缚以及如何构造树呢? 我的意思是- 铲斗会变成一棵树,并会打断领带。然后,我将尝试使用其他实例(具有和)相同的实例来调用方法,它将具有不同的实例,因此是否有可能树被错误的节点遍历(向左而不是向右)并且找不到键? 我是否缺少某些东西,或者这是正常现象? 问题答案: 存储桶将在插入期间使用,但查找仅使用哈希