WeakHashMap 详解
jdk8
本文讨论java.util.package下 WeakHashMap ,为了更好理解数据结构,使用它可以实现简单缓存,并不建议线上环境使用它来,这里只是来帮助理解weakHashmap原理, WeakHashMap 是用哈希表实现 Map 接口,key是 WeekReference 类型, Entry 在 WeakHashMap 被自动删除当 key 不在被使用时候,意味着 key 对象没有被引用,垃圾回收线程会回收 key 对象, Entry 会从map中移除,因此 WeakhHashMap 是另外一种实现 Map 接口
为了更好理解 WeakHashMap ,需要理解弱引用, put() 方法中会把key变成弱引用,java中主要有3中引用,后面部分会介绍
变量prime强引用Integer对象为1值,任何对象被强引用不会被垃圾回收掉
一个对象是软引用不会被垃圾回收器回收直到jvm虚拟机内存不够时候,下面创建软引用案例:
prime对象是强引用,后面把强引用变成软引用,最后prime强引用至为空,prime对象会被垃圾回收当jvm需要内存时候
弱引用对象会被垃圾回收立即,垃圾回收不会等到需要内存时候,下面弱引用案例:
prime设置为空,prime对象将会被垃圾回收在下个垃圾回收周期中,因为这里没有其他强引用指向它
弱引用作为key存在 WeakHashmap 中
建立缓存保存大量图片对象作为值,图像名称作为key,想用一个合适 Map 来解决这个问题,使用 HashMap 不是好的选择,因为对象值会占用很大内存,垃圾回收时候不会被回收,在不使用时候不会被回收,然而,我们想用 Map 接口
能帮我们自动释放内存当key不被使用时候,刚好 WeakHashMap 具备这个特点,下面是案例:
我们创建 WeakHashMap 实例存储BigImage对象,把BigImage对象作为值和imagename作为key,imageName是弱引用存在 Map 中,接下来设置imageName为空,因此没有更多人指向bigImage对象,WeakHashMap默认会删除key在下个垃圾回收阶段
我也可以调用System.gc()强制触发垃圾回收:
注意imageNameFirst引用至为空,imageNameSecond引用保持不变,垃圾回收之后, map 仅存在imageNameSecond
本文讨论java中引用,理解 WeakHashMap 原理,创建一个简单缓存用WeakhashMap来改变缓存对象
参考地址
hashmap 是线程安全的吗
Hashtable.
1 HashMap不是线程安全的
hastmap是一个接口 是map接口的子接口,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值。HashMap允许null key和null value,而hashtable不允许。
2 HashTable是线程安全的一个Collection。
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。
weakhashmap和hashmap的区别
一.HashMap
1.HashMap是基于Key-Value的散列表(JDK7:数组+链表,JDK8:数组+链表+红黑树),采用拉链法实现的。一般用于单线程当中,非线程安全,HashMap的键是"强键"。
2.继承于抽象类AbstractMap,并且实现Map接口。遍历时,取得的数据完全是随机的。
3.默认容量大小是16,加载因子是0.75。
4.最多只允许一条key为Null,允许多条value为Null。
5.HashMap实现了Cloneable和Serializable接口,而WeakHashMap没有。
1).HashMap实现Cloneable,说明它能通过clone()克隆自己。
2).HashMap实现Serializable,说明它支持序列化,能通过序列化去传输。
6.添加、删除操作时间复杂度都是O(1)。
二.weakHashMap
1.weakHashMap是基于Key-Value的散列表(数组+链表),采用拉链法实现的。一般用于单线程当中,非线程安全,weakHashMap中的键是"弱键"。
备注:当"弱键"被GC会收时,它对应的键值也会从weakHashMap中删除。
2.继承于抽象类AbstractMap,并且实现Map接口。
3.默认容量大小是16,加载因子是0.75。
4.最多只允许一条key为Null,允许多条value为Null。
实现原理,如何保证HashMap的线程安全
有2种办法让HashMap线程安全,分别如下:
方法一:通过Collections.synchronizedMap()返回一个新的Map,这个新的map就是线程安全的。 这个要求大家习惯基于接口编程,因为返回的并不是HashMap,而是一个Map的实现。
方法二:重新改写了HashMap,具体的可以查看java.util.concurrent.ConcurrentHashMap. 这个方法比方法一有了很大的改进。