Skip to content

Commit eb98288

Browse files
committed
[A] map: WeakHashMap
1 parent 822856d commit eb98288

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# `WeakHashMap<K,V>`
2+
3+
## 设计
4+
5+
链地址法,不转红黑树。
6+
7+
使用 `WeakReference``Entry` 利用 GC 来回收条目
8+
9+
## 扩容策略
10+
11+
```java
12+
/**
13+
* The default initial capacity -- MUST be a power of two.
14+
*/
15+
private static final int DEFAULT_INITIAL_CAPACITY = 16;
16+
17+
/**
18+
* The load factor used when none specified in constructor.
19+
*/
20+
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
21+
```
22+
23+
达到阈值直接扩容为原来两倍
24+
25+
```java
26+
if (++size >= threshold)
27+
resize(tab.length * 2);
28+
```
29+
30+
## 开源组件拓展
31+
32+
### Tomcat
33+
34+
```java
35+
36+
public final class ConcurrentCache<K,V> {
37+
38+
private final int size;
39+
40+
private final Map<K,V> eden;
41+
42+
private final Map<K,V> longterm;
43+
44+
public ConcurrentCache(int size) {
45+
this.size = size;
46+
this.eden = new ConcurrentHashMap<>(size);
47+
this.longterm = new WeakHashMap<>(size);
48+
}
49+
50+
public V get(K k) {
51+
V v = this.eden.get(k);
52+
if (v == null) {
53+
synchronized (longterm) {
54+
v = this.longterm.get(k);
55+
}
56+
if (v != null) {
57+
this.eden.put(k, v);
58+
}
59+
}
60+
return v;
61+
}
62+
63+
public void put(K k, V v) {
64+
if (this.eden.size() >= size) {
65+
synchronized (longterm) {
66+
this.longterm.putAll(this.eden);
67+
}
68+
this.eden.clear();
69+
}
70+
this.eden.put(k, v);
71+
}
72+
}
73+
```
74+
75+
## 参考
76+
77+
- [Java Reference - TODO](../lang/ref/reference.md)
78+
- [WeakHashMap 的实际使用场景有哪些? - 知乎](https://www.zhihu.com/question/46648593)
79+
- [ConcurrentCache - Tomcat](https://github.com/apache/tomcat/blob/trunk/java/org/apache/tomcat/util/collections/ConcurrentCache.java)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Reference
2+
3+
// todo 问题太多,暂时搁置
4+
5+
## 参考
6+
7+
- [java中的引用 - KL's blog](https://qsli.github.io/2018/07/08/reference/)
8+
- [强软弱虚引用,只有体会过了,才能记住 - CoderBear](https://juejin.im/post/5e65b8096fb9a07cbb6e4a43)
9+
- [回过头来看对象的四种状态强软弱虚引用的理解 - 小勇DW3](https://cloud.tencent.com/developer/article/1198496)
10+
- [进击的Java新人](https://zhuanlan.zhihu.com/p/24393775?refer=hinus)
11+
- [Reference Handler线程的作用](https://zhuanlan.zhihu.com/p/40559078)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
@startuml java-reference-instance-state-transfer
2+
3+
' Active
4+
' Pending
5+
' Enqueued
6+
' Inactive
7+
8+
[*] --> Active
9+
Active : 新创建的 Reference 实例\nnew SoftReference()
10+
11+
note bottom of Pending
12+
13+
SoftReference - GC 时触发状态变更
14+
WeakReference - 非 GC,但是被GC扫描线程扫到了
15+
16+
end note
17+
18+
Active --> Pending : by GC
19+
20+
Pending : 表示引用可以被回收了,\n通知用户层对引用做最后的处理
21+
22+
Active --> Inactive : by GC
23+
24+
Pending -right-> Enqueued : by ReferenceHandler thread
25+
26+
Enqueued -right-> Inactive : 从 ReferenceQueue 移除时\n 一般由用户线程处理\n比如 WeakHashMap#expungeStaleEntries
27+
28+
Inactive : 这个状态 GC 会释放对象
29+
30+
Inactive --> [*]
31+
32+
33+
caption Java引用实例状态转换
34+
35+
right footer https://github.com/c-rainstorm/blog 转载请注明出处
36+
37+
@enduml

0 commit comments

Comments
 (0)