sclass WeakValueMap is AutoCloseable { // A value that has been stored with this key has been garbage // collected. event valueForKeyReleased(A key); // internal Map> map = syncMap(); RunnablesReferenceQueue queue; class MyRef extends WeakRef is Runnable { A key; *(A *key, B value) { super(value, queue()!); } run { syncMapRemoveKeyAndValuePair(map, key, this); valueForKeyReleased(key); } } // public methods follow B get(A key) { ret getWeakRef(map.get(key)); } B put(A key, B value) { if (value == null) { B old = getWeakRef(map.get(key)); map.remove(key); ret old; } else ret getWeakRef(map.put(key, new MyRef(key, value))); } O mutex() { ret collectionMutex(map); } RunnablesReferenceQueue queue() { synchronized(mutex()) { if (queue == null) queue = new RunnablesReferenceQueue; ret queue; } } close { synchronized(mutex()) { dispose queue; } } }