原文地址:
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 ...
谷歌小恐龙HTML源代码
5. **Web API**:一些服务提供API接口,可以直接获取网页源代码,例如Google的Custom Search JSON API。 正确解析网页源代码,需要理解HTML的基本结构和语法规则。HTML由一系列标签组成,每个标签都有开始和结束...
Blob的源代码解析可以从以下几个方面展开: 1. 数据存储:Blob内部有两个成员变量`data_`和`diff_`,它们分别指向实际存储数据和梯度的内存区域。这两个指针可能指向`SyncedMemory`对象,这是一个管理内存分配和CPU...
总的来说,谷歌小恐龙彩蛋源代码的学习可以提供丰富的编程经验,涵盖网页开发的基础和高级概念,如DOM操作、动画制作、事件处理、以及游戏逻辑设计等。无论是对于初学者还是有经验的开发者,这都是一份有价值的参考...
在大多数现代浏览器中,如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 源代码
《深入解析Android 4.2.2源代码》 Android 4.2.2是Google在2012年发布的一个重要版本,它在前代系统的基础上进行了诸多改进和优化,为开发者提供了更加稳定和高效的开发环境。源代码的开放性使得开发者能够深入理解...
本项目标题为"GPS定位并调用谷歌地图源代码",意味着它提供了使用GPS获取位置信息,并在谷歌地图上进行展示的编程实践。以下将详细介绍相关知识点。 1. GPS定位原理:全球定位系统(GPS)通过接收来自多个卫星的...
13. **Material Design**:Google推出的Material Design设计语言在Android开发中广泛使用,源代码可能会展示如何遵循这一设计指南创建界面。 14. **第三方库集成**:许多Android开发者会使用如Butter Knife(注解...