`
dingjob
  • 浏览: 183284 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

WeakHashMap 用法和原理

阅读更多

 在《Effective Java》一书中第六条,消除陈旧对象时,提到了weakHashMap,看了下还是适用的,即在我们使用短时间内就过期的缓存时最好使用weakHashMap,它包含了一个自动调用的方法expungeStaleEntries,这样就会在值被引用后直接执行这个隐含的方法,将不用的键清除掉。

 测试了一下

package com.alibaba.itbu.job.billing;

import java.util.Map;
import java.util.WeakHashMap;

public class WeakHashMapTest {
    static Map wMap = new WeakHashMap();
    public static void init(){
        wMap.put("1", "ding");
        wMap.put("2", "job");
    }
    public static void testWeakHashMap(){

        System.out.println("first get:"+wMap.get("1"));
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("next get:"+wMap.get("1"));
    }
    public static void main(String[] args) {
        testWeakHashMap();
    }
}

 

 

上面例子, 第一次执行时要初始化,然后在5s内是不会清除的,大概在10几秒时会清除

 

第一次执行

first get:ding

next get:ding

 

过一会再执行:

first get:null
next get:null

 

这时候已经被清除

同样,没有调用任何赋值方法的情况下,在一段时间后 size 方法也可能返回较小的值,对于 isEmpty 方法,返回 false,然后返回 true,对于给定的键,containsKey 方法返回 true 然后返回 false,对于给定的键,get 方法返回一个值,但接着返回 null,对于以前出现在映射中的键,put 方法返回 null,而 remove 方法返回 false,对于键集、值集、项集进行的检查,生成的元素数量越来越少。

 

 

注意:WeakHashMap并不是你啥也干他就能自动释放内部不用的对象的,而是在你访问它的内容的时候释放内部不用的对象。这两句话看似区别不大,但是有时候一个小小的区别就会要了命的。就是说你只put 了压根没有get过,这个值是永远都存在的

 

 

 

我们也可以看下这个移除键值的实现

private void expungeStaleEntries() {
	Entry<K,V> e;
        while ( (e = (Entry<K,V>) queue.poll()) != null) {
            int h = e.hash;
            int i = indexFor(h, table.length);

            Entry<K,V> prev = table[i];
            Entry<K,V> p = prev;
            while (p != null) {
                Entry<K,V> next = p.next;
                if (p == e) {
                    if (prev == e)
                        table[i] = next;
                    else
                        prev.next = next;
                    e.next = null;  // Help GC
                    e.value = null; //  "   "
                    size--;
                    break;
                }
                prev = p;
                p = next;
            }
        }
    }

 

 

就是使用了链表,找到这个hash值  将这个hash值移除 size减少

 

 

分享到:
评论
9 楼 szjszj 2017-06-15  
看到请麻烦修改下,以免误人子弟
8 楼 sonofelice 2016-06-04  
博主,你第一段代码怎么没有调用init方法啊~
7 楼 yun900800 2015-04-08  
这是害人啦
6 楼 fortaotao 2015-01-16  
这治学态度太不严谨了吧,贴出来的例子压根自己就没检查过。
5 楼 transist 2012-01-04  
是否WeakHashMap不适用于传递中间数据使用?经测试好像会丢掉一些key
4 楼 zhenlishiwo 2011-03-07  
因为String的特殊性,楼主的代码是不可能实现的,看下面代码
WeakHashMap wMap = new WeakHashMap();
Person p1 = new Person("张三");
Person p2 = new Person("李四");	
wMap.put(p1, "zs");
wMap.put(p2, "ls");
p1=null;
//gc,不保证运行
try {
	System.gc();
	Thread.sleep(1000);
	} catch (InterruptedException e) {
		e.printStackTrace();
	}

for (Object o : wMap.entrySet()) {
	System.out.println(o);
}
3 楼 zhenlishiwo 2011-03-07  
WeakHashMap wMap = new WeakHashMap();
Person p1 = new Person("张三");
Person p2 = new Person("李四");
wMap.put(p1, "zs");
wMap.put(p2, "ls");
p1=null;
//gc
try {
System.gc();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

for (Object o : wMap.entrySet()) {
System.out.println(o);
}
2 楼 zhenlishiwo 2011-03-02  
经jdk1.5测试,该例子没有通过
1 楼 darrendu 2011-01-04  
楼上,你的测试不给力啊,把你的测试改下也不行,那里错了吗
my code
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.TimeUnit;

public class WeakHashMapTest {
    static Map wMap = new WeakHashMap();
    public static void init(){
        wMap.put("1", "ding");
        wMap.put("2", "job");
    }
    public static void testWeakHashMap(){

        System.out.println("first get:"+wMap.get("1"));
        try {
        	System.gc();
            TimeUnit.SECONDS.sleep(20);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("next get:"+wMap.get("1"));
    }
    public static void main(String[] args) {
    	init();
        testWeakHashMap();
    }
}

相关推荐

    Java编程WeakHashMap实例解析

    WeakHashMap的实现原理是使用WeakReference来保存键和值,WeakReference是一个弱引用的实现,它可以在垃圾回收器清理对象时自动清理对象的引用。在WeakHashMap中,每个键和值都是WeakReference对象,这样可以使得...

    弱类型语言允许将一块内存看做多种类型

    - **expungeStaleEntries 方法**:为了确保 WeakHashMap 的键被正确清理,每当访问 WeakHashMap 的时候,都会调用 expungeStaleEntries 方法来清除已经无效的键值对。 #### 七、WeakHashMap 的局限性 - **访问触发...

    线程死锁CPU过高,请求原因分析

    线程死锁是多线程编程中一个严重的问题...理解这些原理和方法对于预防和解决Java中的线程死锁和CPU过高问题至关重要。开发者需要深入理解线程同步机制、弱引用的特性以及性能优化技巧,以确保应用程序的稳定性和效率。

    java数据结构课件与分析

    学习栈的原理和在回溯算法、表达式求值等问题中的应用。 4. **队列**:先进先出(FIFO)的数据结构,如`java.util.Queue`接口。理解队列的工作原理,以及优先队列(PriorityQueue)的概念。 5. **集合框架**:Java...

    2013年java开发最常见的笔试面试题大总结

    1. List、Set、Queue:了解这些接口的特点,以及ArrayList、LinkedList、HashSet、TreeSet等常见实现类的内部原理和使用场景。 2. Map接口:理解HashMap、TreeMap、WeakHashMap等实现,以及键值对的存取方式。 3. ...

    Java集合框架完整说明便于了解集合

    理解并熟练掌握Java集合框架是每个Java开发者的基础,这不仅包括接口的使用,还涉及到它们的实现原理和性能优化。在实际开发中,根据需求选择合适的集合类型,可以极大地提高代码的效率和可维护性。

    SCJP Sun Certified Programmer for java 6 Study Guide(Exam 310-065)

    - **通道与缓冲区**:NIO中的Channel和Buffer类及其使用方法。 11. **反射** - **Class类**:通过Class对象获取类的信息。 - **动态创建对象和调用方法**:使用newInstance()和invoke()方法实现运行时操作。 12...

    张孝祥java就业面试题宝典

    2. 继承与多态:理解单一继承和接口多实现,掌握抽象方法和final关键字的使用,探讨多态的实现方式。 3. 包与访问修饰符:了解包的组织结构,掌握public、private、protected等访问权限。 4. 内部类与匿名类:理解...

    JAVA面试常见题型全集

    1. 类与对象:理解类的构造器、属性和方法,掌握对象的创建与使用。 2. 继承与多态:理解单继承和多层继承,以及接口实现,了解抽象类和接口的区别。 3. 访问控制:掌握public、private、protected以及默认访问修饰...

    预习,2、内存分配与回收策略~深入理解垃圾回收器1

    理解GC的工作原理和内存分配策略对于优化应用性能、避免内存溢出等问题至关重要。 Java中的内存主要分为三个区域:栈、堆和方法区/元空间。栈主要用于存储局部变量和方法调用的信息,它的生命周期跟随线程,因此...

    java基础之集合面试题共4页.pdf.zip

    HashMap、TreeMap、LinkedHashMap和WeakHashMap是主要的实现。HashMap提供了快速的查找,TreeMap保持键的排序,LinkedHashMap保持插入顺序或访问顺序,WeakHashMap则允许弱引用键。 6. **泛型**:Java集合框架广泛...

    1-Collections-Overview-Section-Java-Collections-S_overview

    WeakHashMap和IdentityHashMap则提供了特殊的键引用策略。 3. 工具类: - **Collections**: 提供了一系列静态方法,用于操作集合,如排序、查找、填充、反转等。 - **Arrays**: 用于处理数组,包含排序、比较、...

    Java核心知识点整理_java_

    Java是一种广泛使用的面向...以上是Java核心知识点的概览,包括基础语法、JVM的工作原理和垃圾回收机制,这些都是Java开发中不可或缺的部分。深入理解和掌握这些知识点,对于提升编程技能和解决实际问题具有重要意义。

    java面试题java面试题

    - **Map接口与实现**:HashMap、TreeMap、LinkedHashMap的区别,以及WeakHashMap和ConcurrentHashMap的应用。 - **泛型**:理解泛型的限制、通配符和类型擦除。 3. **多线程**: - **线程创建**:通过Thread类和...

    java面试常问基础知识总结(超经典)

    7. **网络编程**:涉及Socket编程,包括TCP和UDP协议,理解网络通信的基本原理和Java如何实现网络连接,以及套接字(Socket和ServerSocket)的使用。 8. **反射**:Java反射机制允许在运行时动态地获取类的信息和...

    Android异步加载图像小结 (含线程池,缓存方法).zip

    同时,可以自定义缓存策略,如使用`WeakHashMap`作为内存缓存,配合`SharedPreferences`或文件系统实现磁盘缓存。 总的来说,Android异步加载图像涉及到多线程编程、缓存策略以及性能优化等多个方面。通过合理使用...

    2018最新Java面试题详细版.zip_2018 面试_E98_Java面试题2018_java2018面试_java面试

    - **同步机制**:学习synchronized关键字的用法,包括同步方法和同步块,以及 volatile 关键字的作用。 - **死锁**:理解死锁的概念,如何避免和解决死锁问题。 - **线程池**:掌握ExecutorService,...

    20个最佳的Java集合框架面试题目.zip

    HashMap、TreeMap、WeakHashMap和ConcurrentHashMap是常见的实现。 8. **并发处理**:在多线程环境下,集合框架中的ConcurrentHashMap、CopyOnWriteArrayList和CopyOnWriteArraySet提供了线程安全的解决方案。 9. ...

    高级java工程师面试考纲,java高级工程师进阶知识地图

    - **MVC框架**:至少熟练掌握一种MVC框架(如SpringMVC、Struts)的工作原理和使用方法。 - **ORM框架**:至少精通一个ORM框架(如Hibernate、MyBatis),理解对象关系映射的概念及其在项目中的应用。 #### 数据...

Global site tag (gtag.js) - Google Analytics