public class WeakHashMap extends AbstractMap implements Map {
...
private final ReferenceQueue queue = new ReferenceQueue<>();
...
//重点
private void expungeStaleEntries() {
//需要注意queue.poll()是不阻塞的,remove(long time)方法是阻塞的
for (Object x; (x = queue.poll()) != null; ) {
synchronized (queue) {
@SuppressWarnings("unchecked")
Entry e = (Entry) x;
int i = indexFor(e.hash, table.length);
Entry prev = table[i];
Entry p = prev;
//同时在这里我们也可以看出WeakHashMap底层采用数组+链表并未使用红黑树
while (p != null) {
Entry next = p.next;
if (p == e) {
if (prev == e)
table[i] = next;
else
prev.next = next;
// Must not null out e.next;
// stale entries may be in use by a HashIterator
e.value = null; // Help GC
size--;
break;
}
prev = p;
p = next;
}
}
}
}
}
ReferenceQueue的remove与poll方法
//并未阻塞
public Reference extends T> poll() {
if (head == null)
return null;
synchronized (lock) {
return reallyPoll();
}
}
//通过lock.wait(timeout);阻塞调用remove方法的线程
public Reference extends T> remove(long timeout)
throws IllegalArgumentException, InterruptedException
{
...
synchronized (lock) {
Reference extends T> r = reallyPoll();
if (r != null) return r;
long start = (timeout == 0) ? 0 : System.nanoTime();
for (;;) {
lock.wait(timeout);
r = reallyPoll();
if (r != null) return r;
if (timeout != 0) {
long end = System.nanoTime();
timeout -= (end - start) / 1000_000;
if (timeout <= 0) return null;
start = end;
}
}
}
}