<code>// 首先从map中取,看看缓存能否命中,是否过期 ReferenceEntry getLiveEntry(Object key, int hash, long now) { // 从segment的原子数组中获取kv键值对 ReferenceEntry e = getEntry(key, hash); if (e == null) { return null; } else if (map.isExpired(e, now)) { // 此时仅仅是使用ReentrantLock.tryLock尝试获取锁(CAS方式轻量级获取锁) tryExpireEntries(now); return null; } return e; } // ReentrantLock.tryLock 非公平锁实现 final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { // CAS方式轻量级获取锁,性能开销小 if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; } // 如果缓存没有命中 V lockedGetOrLoad(K key, int hash, CacheLoader super K, V> loader) throws ExecutionException { ReferenceEntry e; ValueReference valueReference = null; LoadingValueReference loadingValueReference = null; boolean createNewEntry = true; lock(); try { long now = map.ticker.read(); // 占有锁后,进行一次集中的清理 preWriteCleanup(now); ...... } } // 集中的清理 void runLockedCleanup(long now) { if (tryLock()) { try { // 此处清理软引用与弱引用的键值对 drainReferenceQueues(); expireEntries(now); // calls drainRecencyQueue readCount.set(0); } finally { unlock(); } } } void expireEntries(long now) { // recencyQueue来更新accessQueue元素,保证accessQueue的先进先出逻辑 drainRecencyQueue(); ReferenceEntry e; while ((e = writeQueue.peek()) != null && map.isExpired(e, now)) { if (!removeEntry (e, e.getHash(), RemovalCause.EXPIRED)) { throw new AssertionError(); } } while ((e = accessQueue.peek()) != null && map.isExpired(e, now)) { if (!removeEntry(e, e.getHash(), RemovalCause.EXPIRED)) { throw new AssertionError(); } } } // 从AtomicReferenceArray,writeQueue、accessQueue这3个数据结构中移除该ntry boolean removeEntry(ReferenceEntry entry, int hash, RemovalCause cause) { int newCount = this.count - 1; AtomicReferenceArray> table = this.table; int index = hash & (table.length() - 1); ReferenceEntry first = table.get(index); for (ReferenceEntry e = first; e != null; e = e.getNext()) { if (e == entry) { ++modCount; ReferenceEntry newFirst = removeValueFromChain( first, e, e.getKey(), hash, e.getValueReference(), cause); newCount = this.count - 1; // 调整hash数组 table.set(index, newFirst); this.count = newCount; // write-volatile return true; } } return false; }/<code>