java中利用WeakHashMap实现缓存
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java中利用WeakHashMap实现缓存,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4225字,纯文字阅读大概需要7分钟。
内容图文
简介
WeakHashMap是Java集合框架里的一员,从名字可以看出它是某种 Map。它的特殊之处在于 WeakHashMap 里的entry
可能会被GC自动删除,即使程序员没有调用remove()
或者clear()
方法。
更直观的说,当使用 WeakHashMap 时,即使没有显示的添加或删除任何元素,也可能发生如下情况:
- 调用两次
size()
方法返回不同的值;- 两次调用
isEmpty()
方法,第一次返回false
,第二次返回true
;- 两次调用
containsKey()
方法,第一次返回true
,第二次返回false
,尽管两次使用的是同一个key
;- 两次调用
get()
方法,第一次返回一个value
,第二次返回null
,尽管两次使用的是同一个对象。
遇到这么奇葩的现象,你是不是觉得使用者一定会疯掉?其实不然,WeekHashMap 的这个特点特别适用于需要缓存的场景。在缓存场景下,由于内存是有限的,不能缓存所有对象;对象缓存命中可以提高系统效率,但缓存MISS也不会造成错误,因为可以通过计算重新得到。
要明白 WeekHashMap 的工作原理,还需要引入一个概念:弱引用(WeakReference)。我们都知道Java中内存是通过GC自动管理的,GC会在程序运行过程中自动判断哪些对象是可以被回收的,并在合适的时机进行内存释放。GC判断某个对象是否可被回收的依据是,是否有有效的引用指向该对象。如果没有有效引用指向该对象(基本意味着不存在访问该对象的方式),那么该对象就是可回收的。这里的“有效引用”并不包括弱引用。也就是说,虽然弱引用可以用来访问对象,但进行垃圾回收时弱引用并不会被考虑在内,仅有弱引用指向的对象仍然会被GC回收。
WeakHashMap 内部是通过弱引用来管理entry
的,弱引用的特性对应到 WeakHashMap 上意味着什么呢?将一对key, value
放入到 WeakHashMap 里并不能避免该key
值被GC回收,除非在 WeakHashMap 之外还有对该key
的强引用。
关于强引用,弱引用等概念以后再具体讲解,这里只需要知道Java中引用也是分种类的,并且不同种类的引用对GC的影响不同就够了。
是否有WeekHashSet?
答案是没有:( 。不过Java Collections工具类给出了解决方案,Collections.newSetFromMap(Map<E,Boolean> map)
方法可以将任何 Map包装成一个Set。通过如下方式可以快速得到一个 Weak HashSet:
// 将WeakHashMap包装成一个Set Set<Object> weakHashSet = Collections.newSetFromMap( new WeakHashMap<Object, Boolean>());
不出你所料,newSetFromMap()
方法只是对传入的 Map做了简单包装:
// Collections.newSetFromMap()用于将任何Map包装成一个Set public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) { returnnew SetFromMap<>(map); } privatestaticclass SetFromMap<E> extends AbstractSet<E> implements Set<E>, Serializable { privatefinal Map<E, Boolean> m; // The backing mapprivatetransient Set<E> s; // Its keySet SetFromMap(Map<E, Boolean> map) { if (!map.isEmpty()) thrownew IllegalArgumentException("Map is non-empty"); m = map; s = map.keySet(); } publicvoid clear() { m.clear(); } publicint size() { return m.size(); } publicboolean isEmpty() { return m.isEmpty(); } publicboolean contains(Object o) { return m.containsKey(o); } publicboolean remove(Object o) { return m.remove(o) != null; } publicboolean add(E e) { return m.put(e, Boolean.TRUE) == null; } public Iterator<E> iterator() { return s.iterator(); } public Object[] toArray() { return s.toArray(); } public <T> T[] toArray(T[] a) { return s.toArray(a); } public String toString() { return s.toString(); } publicint hashCode() { return s.hashCode(); } publicboolean equals(Object o) { return o == this || s.equals(o); } publicboolean containsAll(Collection<?> c) {return s.containsAll(c);} publicboolean removeAll(Collection<?> c) {return s.removeAll(c);} publicboolean retainAll(Collection<?> c) {return s.retainAll(c);} // addAll is the only inherited implementation ...... }
// Collections.newSetFromMap()用于将任何Map包装成一个Set
public
static
<E> Set<E> newSetFromMap(Map<E, Boolean> map) {
return
new
SetFromMap<>(map);
}
private
static
class
SetFromMap<E>
extends
AbstractSet<E>
implements
Set<E>, Serializable
{
private
final
Map<E, Boolean> m;
// The backing map
private
transient
Set<E> s;
// Its keySet
SetFromMap(Map<E, Boolean> map) {
if
(!map.isEmpty())
throw
new
IllegalArgumentException(
"Map is non-empty"
);
m = map;
s = map.keySet();
}
public
void
clear() { m.clear(); }
public
int
size() {
return
m.size(); }
public
boolean
isEmpty() {
return
m.isEmpty(); }
public
boolean
contains(Object o) {
return
m.containsKey(o); }
public
boolean
remove(Object o) {
return
m.remove(o) !=
null
; }
public
boolean
add(E e) {
return
m.put(e, Boolean.TRUE) ==
null
; }
public
Iterator<E> iterator() {
return
s.iterator(); }
public
Object[] toArray() {
return
s.toArray(); }
public
<T> T[] toArray(T[] a) {
return
s.toArray(a); }
public
String toString() {
return
s.toString(); }
public
int
hashCode() {
return
s.hashCode(); }
public
boolean
equals(Object o) {
return
o ==
this
|| s.equals(o); }
public
boolean
containsAll(Collection<?> c) {
return
s.containsAll(c);}
public
boolean
removeAll(Collection<?> c) {
return
s.removeAll(c);}
public
boolean
retainAll(Collection<?> c) {
return
s.retainAll(c);}
// addAll is the only inherited implementation
......
}
原文:https://www.cnblogs.com/shamo89/p/9216529.html
内容总结
以上是互联网集市为您收集整理的java中利用WeakHashMap实现缓存全部内容,希望文章能够帮你解决java中利用WeakHashMap实现缓存所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。