jodd-core/src/main/java/jodd/cache/AbstractCacheMap.java
@Override
	public V get(final K key) {
		long stamp = lock.readLock();

		try {
			CacheObject<K,V> co = cacheMap.get(key);
			if (co == null) {
				missCount++;
				return null;
			}
			if (co.isExpired()) {
				final long newStamp = lock.tryConvertToWriteLock(stamp);

				if (newStamp != 0L) {
					stamp = newStamp;
					// lock is upgraded to write lock
				}
				else {
					// manually upgrade lock to write lock
					lock.unlockRead(stamp);
					stamp = lock.writeLock();
				}

				CacheObject<K,V> removedCo = cacheMap.remove(key);
				if (removedCo != null) {
					onRemove(removedCo.key, removedCo.cachedObject);
				}

				missCount++;
				return null;
			}

			hitCount++;
			return co.getObject();
		}
		finally {
			lock.unlock(stamp);
		}
	}
@Override
	public V get(final K key) {
		long stamp = lock.readLock();

		try {
			CacheObject<K,V> co = cacheMap.get(key);
			if (co == null) {
				missCount++;
				return null;
			}
			if (co.isExpired()) {
				final long newStamp = lock.tryConvertToWriteLock(stamp);

				if (newStamp != 0L) {
					stamp = newStamp;
					// lock is upgraded to write lock
				}
				else {
					// manually upgrade lock to write lock
					lock.unlockRead(stamp);
					stamp = lock.writeLock();
				}

				CacheObject<K,V> removedCo = cacheMap.remove(key);
				if (removedCo != null) {
					onRemove(removedCo.key, removedCo.cachedObject);
				}

				missCount++;
				return null;
			}

			hitCount++;
			return co.getObject();
		}
		finally {
			lock.unlock(stamp);
		}
	}
{@inheritDoc}