`
janeky
  • 浏览: 365938 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

google的ConcurrentLinkedHashmap源代码解析

阅读更多

简述

ConcurrentLinkedHashMap 是google团队提供的一个容器。它有什么用呢?其实它本身是对

 

ConcurrentHashMap的封装,可以用来实现一个基于LRU策略的缓存。详细介绍可以参见 

 

http://code.google.com/p/concurrentlinkedhashmap

 

使用范例

public static void main(String[] args) {
ConcurrentLinkedHashMap<Integer, Integer> map = new 
	ConcurrentLinkedHashMap.Builder<Integer,Integer>().maximumWeightedCapacity(2).
        weigher(Weighers.singleton()).build();
		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函数

 

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 是判断是否容量满了,需要剔除其他元素

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节点移至队列头

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

  • 大小: 7.3 KB
  • 大小: 46 KB
3
3
分享到:
评论
1 楼 BuN_Ny 2012-05-18  
不错。·~~~~~

相关推荐

    google搜搜 源代码

    【标签】"google搜搜 源代码"再次确认了该压缩包的内容,意味着它包含的文件与Google搜索引擎的源代码有关,可能是仿造的、修改的,或者是对原版Google搜索算法的解析或实现。 【压缩包子文件的文件名称列表】: 1....

    google protobuf 最新源代码

    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源代码

    谷歌小恐龙HTML源代码

    caffe源代码解析

    Blob的源代码解析可以从以下几个方面展开: 1. 数据存储:Blob内部有两个成员变量`data_`和`diff_`,它们分别指向实际存储数据和梯度的内存区域。这两个指针可能指向`SyncedMemory`对象,这是一个管理内存分配和CPU...

    谷歌小恐龙彩蛋源代码

    总的来说,谷歌小恐龙彩蛋源代码的学习可以提供丰富的编程经验,涵盖网页开发的基础和高级概念,如DOM操作、动画制作、事件处理、以及游戏逻辑设计等。无论是对于初学者还是有经验的开发者,这都是一份有价值的参考...

    查看网页源代码查看网页源代码

    在大多数现代浏览器中,如Google Chrome、Firefox、Microsoft Edge或Safari,你可以通过以下步骤来查看源代码: 1. 打开你想要查看源代码的网页。 2. 右键点击页面,选择“查看网页源代码”或“审查元素”(Inspect...

    google 标准的图像浏览器源代码

    在深入探讨Google标准图像浏览器源代码之前,我们先来理解一下图像浏览器在移动设备上的重要性。一个良好的图像浏览器能够帮助用户轻松地查看、管理、分享和编辑他们的照片。Google作为全球领先的科技公司,其在...

    猫影视源代码JAVA开源 Andriod studio 源代码工程文件 有能力可自行二开

    【标题】"猫影视源代码JAVA开源 Andriod Studio 源代码工程文件 有能力可自行二开"指的是一个基于Java编程语言开发的Android应用程序——猫影视的源代码项目。这个开源项目允许开发者查看、学习甚至修改源代码,以...

    Google Android 应用开发揭秘 源代码

    "Google Android 应用开发揭秘 源代码"提供了深入理解Android应用构建过程的机会,让我们能够直接探索那些专业开发者是如何实现各种功能和交互的。这个压缩包包含了《Android应用开发揭秘》一书的源码,这本书可能是...

    安卓即时通讯工具源代码

    1. **用户身份验证**:用户注册和登录通常涉及到服务器端的数据存储和验证,源代码中可能会包含网络请求库(如OkHttp或Volley)的使用,以及JSON解析(如Gson或Jackson)来处理服务器返回的数据。 2. **消息传输**...

    google搜索源代码

    google搜索源代码

    《TensorFlow技术解析与实战》配套源代码

    《TensorFlow技术解析与实战》是一本专注于深度学习框架TensorFlow的专业书籍,旨在帮助读者深入...因此,对于想要深入学习和应用TensorFlow的开发者来说,《TensorFlow技术解析与实战》的配套源代码是一份宝贵的资源。

    google map api开发源代码

    这个源代码压缩包提供了一种实现Google Map API二次开发的实例,对于想要深入理解和应用这一技术的人来说非常有价值。 首先,我们要理解Google Map API的基本概念。它是一个JavaScript库,通过在网页中引入特定的...

    labview调用google地图源代码.zip源码Labview个人项目资料程序资源下载

    labview调用google地图源代码.zip源码Labview个人项目资料程序资源下载labview调用google地图源代码.zip源码Labview个人项目资料程序资源下载labview调用google地图源代码.zip源码Labview个人项目资料程序资源下载...

    google源代码

    google 源代码

    Android 4.2.2源代码

    《深入解析Android 4.2.2源代码》 Android 4.2.2是Google在2012年发布的一个重要版本,它在前代系统的基础上进行了诸多改进和优化,为开发者提供了更加稳定和高效的开发环境。源代码的开放性使得开发者能够深入理解...

    GPS定位并调用谷歌地图源代码

    本项目标题为"GPS定位并调用谷歌地图源代码",意味着它提供了使用GPS获取位置信息,并在谷歌地图上进行展示的编程实践。以下将详细介绍相关知识点。 1. GPS定位原理:全球定位系统(GPS)通过接收来自多个卫星的...

    Android经典项目开发实战_源代码

    13. **Material Design**:Google推出的Material Design设计语言在Android开发中广泛使用,源代码可能会展示如何遵循这一设计指南创建界面。 14. **第三方库集成**:许多Android开发者会使用如Butter Knife(注解...

Global site tag (gtag.js) - Google Analytics