原文地址:
http://janeky.iteye.com/blog/1534352
简述
ConcurrentLinkedHashMap 是google团队提供的一个容器。它有什么用呢?其实它本身是对
ConcurrentHashMap的封装,可以用来实现一个基于LRU策略的缓存。详细介绍可以参见
http://code.google.com/p/concurrentlinkedhashmap
使用范例
Java代码 收藏代码
public static void main(String[] args) {
ConcurrentLinkedHashMap<Integer, Integer> map = new
<span style="white-space: pre;"> </span>ConcurrentLinkedHashMap.Builder<Integer,Integer>().maximumWeightedCapacity(2).
Java代码 收藏代码
weigher(Weighers.singleton()).build();
Java代码 收藏代码
map.put(1, 1);
map.put(2, 2);
map.put(3, 3);
System.out.println(map.get(1));//null 已经失效了
System.out.println(map.get(2));
ConcurrentLinkedHashMap 的构造函数比较特殊,它采用了Builder(构造器,GOF模式之一)。
它本身也是实现了ConcurrentMap接口的,所以使用起来跟ConcurrentHashMap一样。我们先put
进去三个元素,然后获取第一个元素,果然是null,因为基于LRU(最近使用)算法,key=1的节
点已经失效了。
源代码解析
先来看看它的整体框架
它本质是额外维护了一个双向链表,每次读和写都要改变相应节点的位置,将其移至队列头。
什么时候判断容易已经满了,是根据weight。每个元素都有一个weight,每增加一个元素,weight累计。当达到最大值的时候,就需要剔除最少操作的那个元素了,并且触发相关的事件。
我们先来看put函数
Java代码 收藏代码
V put(K key, V value, boolean onlyIfAbsent) {
checkNotNull(value);
final int weight = weigher.weightOf(key, value);//计算weight
final WeightedValue<V> weightedValue = new WeightedValue<V>(value, weight);
final Node node = new Node(key, weightedValue);//对数据进行包装,准备存入
ConcurrentHashMap
for (;;) {
final Node prior = data.putIfAbsent(node.key, node);
if (prior == null) {//这个key之前没有值
afterCompletion(new AddTask(node, weight));//更新后续操作
return null;
} else if (onlyIfAbsent) {
afterCompletion(new ReadTask(prior));
return prior.getValue();
}
AddTask 是判断是否容量满了,需要剔除其他元素
Java代码 收藏代码
final class AddTask extends AbstractTask {
final Node node;
final int weight;
@Override
@GuardedBy("evictionLock")
public void run() {
weightedSize += weight;
// ignore out-of-order write operations
if (node.get().isAlive()) {
evictionDeque.add(node);
evict();//是否移除失效的
}
}
}
void evict() {
while (hasOverflowed()) {
Node node = evictionDeque.poll();
// If weighted values are used, then the pending operations will adjust
// the size to reflect the correct weight
if (node == null) {
return;
}
// Notify the listener only if the entry was evicted
if (data.remove(node.key, node)) {//移除失效的
pendingNotifications.add(node);
}
node.makeDead();
}
}
get函数更简单一点,只是将这个key节点移至队列头
Java代码 收藏代码
public V get(Object key) {
final Node node = data.get(key);
if (node == null) {
return null;
}
afterCompletion(new ReadTask(node));
return node.getValue();
}
性能比较 vs ConcurrentHashMap
不用说了,肯定是ConcurrentHashMap要好一点了,因为本文的主角还要维护一个操作队列嘛:)
不过性能上不是差很多,见下图。
总结:
利用ConcurrentLinkedHashMap来做基于LRU的缓存,还是值得推荐的。我们可以定义它的容器大小,基于LRU,就可以保证较高的命中率了。
参考资料:
http://code.google.com/p/concurrentlinkedhashmap
分享到:
相关推荐
【标签】"google搜搜 源代码"再次确认了该压缩包的内容,意味着它包含的文件与Google搜索引擎的源代码有关,可能是仿造的、修改的,或者是对原版Google搜索算法的解析或实现。 【压缩包子文件的文件名称列表】: 1....
google protobuf 最新源代码google protobuf 最新源代码google protobuf 最新源代码google protobuf 最新源代码google protobuf 最新源代码google protobuf 最新源代码google protobuf 最新源代码google protobuf ...
5. **Web API**:一些服务提供API接口,可以直接获取网页源代码,例如Google的Custom Search JSON API。 正确解析网页源代码,需要理解HTML的基本结构和语法规则。HTML由一系列标签组成,每个标签都有开始和结束...
谷歌小恐龙HTML源代码
Blob的源代码解析可以从以下几个方面展开: 1. 数据存储:Blob内部有两个成员变量`data_`和`diff_`,它们分别指向实际存储数据和梯度的内存区域。这两个指针可能指向`SyncedMemory`对象,这是一个管理内存分配和CPU...
在大多数现代浏览器中,如Google Chrome、Firefox、Microsoft Edge或Safari,你可以通过以下步骤来查看源代码: 1. 打开你想要查看源代码的网页。 2. 右键点击页面,选择“查看网页源代码”或“审查元素”(Inspect...
在深入探讨Google标准图像浏览器源代码之前,我们先来理解一下图像浏览器在移动设备上的重要性。一个良好的图像浏览器能够帮助用户轻松地查看、管理、分享和编辑他们的照片。Google作为全球领先的科技公司,其在...
【标题】"猫影视源代码JAVA开源 Andriod Studio 源代码工程文件 有能力可自行二开"指的是一个基于Java编程语言开发的Android应用程序——猫影视的源代码项目。这个开源项目允许开发者查看、学习甚至修改源代码,以...
"Google Android 应用开发揭秘 源代码"提供了深入理解Android应用构建过程的机会,让我们能够直接探索那些专业开发者是如何实现各种功能和交互的。这个压缩包包含了《Android应用开发揭秘》一书的源码,这本书可能是...
1. **用户身份验证**:用户注册和登录通常涉及到服务器端的数据存储和验证,源代码中可能会包含网络请求库(如OkHttp或Volley)的使用,以及JSON解析(如Gson或Jackson)来处理服务器返回的数据。 2. **消息传输**...
google搜索源代码
《TensorFlow技术解析与实战》是一本专注于深度学习框架TensorFlow的专业书籍,旨在帮助读者深入...因此,对于想要深入学习和应用TensorFlow的开发者来说,《TensorFlow技术解析与实战》的配套源代码是一份宝贵的资源。
这个源代码压缩包提供了一种实现Google Map API二次开发的实例,对于想要深入理解和应用这一技术的人来说非常有价值。 首先,我们要理解Google Map API的基本概念。它是一个JavaScript库,通过在网页中引入特定的...
labview调用google地图源代码.zip源码Labview个人项目资料程序资源下载labview调用google地图源代码.zip源码Labview个人项目资料程序资源下载labview调用google地图源代码.zip源码Labview个人项目资料程序资源下载...
google 源代码
这个“谷歌小恐龙彩蛋源代码”是一个Python实现的版本,允许开发者和爱好者研究其背后的实现机制,并进行自定义或扩展。 在“DinoRunTutorial-master”这个压缩包文件中,我们可以期待找到关于这个游戏的全部源代码...
《深入解析Android 4.2.2源代码》 Android 4.2.2是Google在2012年发布的一个重要版本,它在前代系统的基础上进行了诸多改进和优化,为开发者提供了更加稳定和高效的开发环境。源代码的开放性使得开发者能够深入理解...
本项目标题为"GPS定位并调用谷歌地图源代码",意味着它提供了使用GPS获取位置信息,并在谷歌地图上进行展示的编程实践。以下将详细介绍相关知识点。 1. GPS定位原理:全球定位系统(GPS)通过接收来自多个卫星的...
这个源代码包是GMAP.net的最新官方版本,对于任何希望深入理解地图应用开发或者想要自定义地图功能的人来说,都是宝贵的资源。 首先,GMAP.net的核心特性之一是其跨平台的支持。它可以在Windows Forms、WPF、ASP...
在你提供的信息中,“json 源代码”可能是指用于处理JSON数据的源代码库,例如解析、生成和操作JSON对象的函数或类。Android框架也包含对JSON的支持,这部分源代码可能是从Android框架中提取出来的一个部分,供...