cache.java
来自「一个不错的cache」· Java 代码 · 共 884 行 · 第 1/3 页
JAVA
884 行
*/ public void removeCacheEventListener(CacheEventListener listener, Class clazz) { listenerList.remove(clazz, listener); } /** * Get an entry from this cache or create one if it doesn't exist. * * @param key The key of the cache entry * @param policy Object that implements refresh policy logic * @param origin The origin of request (optional) * @return CacheEntry for the specified key. */ protected CacheEntry getCacheEntry(String key, EntryRefreshPolicy policy, String origin) { CacheEntry cacheEntry = null; // Verify that the key is valid if ((key == null) || (key.length() == 0)) { throw new IllegalArgumentException("getCacheEntry called with an empty or null key"); } cacheEntry = (CacheEntry) cacheMap.get(key); // if the cache entry does not exist, create a new one if (cacheEntry == null) { if (log.isDebugEnabled()) { log.debug("No cache entry exists for key='" + key + "', creating"); } cacheEntry = new CacheEntry(key, policy); } return cacheEntry; } /** * Indicates whether or not the cache entry is stale. * * @param cacheEntry The cache entry to test the freshness of. * @param refreshPeriod The maximum allowable age of the entry, in seconds. * @param cronExpiry A cron expression specifying absolute date(s) and/or time(s) * that the cache entry should expire at. If the cache entry was refreshed prior to * the most recent match for the cron expression, the entry will be considered stale. * * @return <code>true</code> if the entry is stale, <code>false</code> otherwise. */ protected boolean isStale(CacheEntry cacheEntry, int refreshPeriod, String cronExpiry) { boolean result = cacheEntry.needsRefresh(refreshPeriod) || isFlushed(cacheEntry); if ((cronExpiry != null) && (cronExpiry.length() > 0)) { try { FastCronParser parser = new FastCronParser(cronExpiry); result = result || parser.hasMoreRecentMatch(cacheEntry.getLastUpdate()); } catch (ParseException e) { log.warn(e); } } return result; } /** * Get the updating cache entry from the update map. If one is not found, * create a new one (with state {@link EntryUpdateState#NOT_YET_UPDATING}) * and add it to the map. * * @param key The cache key for this entry * * @return the CacheEntry that was found (or added to) the updatingEntries * map. */ protected EntryUpdateState getUpdateState(String key) { EntryUpdateState updateState; synchronized (updateStates) { // Try to find the matching state object in the updating entry map. updateState = (EntryUpdateState) updateStates.get(key); if (updateState == null) { // It's not there so add it. updateState = new EntryUpdateState(); updateStates.put(key, updateState); } } return updateState; } /** * Completely clears the cache. */ protected void clear() { cacheMap.clear(); } /** * Removes the update state for the specified key and notifies any other * threads that are waiting on this object. This is called automatically * by the {@link #putInCache} method. * * @param key The cache key that is no longer being updated. */ protected void completeUpdate(String key) { EntryUpdateState state; synchronized (updateStates) { state = (EntryUpdateState) updateStates.remove(key); if (state != null) { synchronized (state) { if (!state.isUpdating()) { state.startUpdate(); } state.completeUpdate(); state.notifyAll(); } } } } /** * Completely removes a cache entry from the cache and its associated cache * groups. * * @param key The key of the entry to remove. */ protected void removeEntry(String key) { removeEntry(key, null); } /** * Completely removes a cache entry from the cache and its associated cache * groups. * * @param key The key of the entry to remove. * @param origin The origin of this remove request. */ protected void removeEntry(String key, String origin) { CacheEntry cacheEntry = (CacheEntry) cacheMap.get(key); cacheMap.remove(key); if (listenerList.getListenerCount() > 0) { CacheEntryEvent event = new CacheEntryEvent(this, cacheEntry, origin); dispatchCacheEntryEvent(CacheEntryEventType.ENTRY_REMOVED, event); } } /** * Dispatch a cache entry event to all registered listeners. * * @param eventType The type of event (used to branch on the proper method) * @param event The event that was fired */ private void dispatchCacheEntryEvent(CacheEntryEventType eventType, CacheEntryEvent event) { // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == CacheEntryEventListener.class) { if (eventType.equals(CacheEntryEventType.ENTRY_ADDED)) { ((CacheEntryEventListener) listeners[i + 1]).cacheEntryAdded(event); } else if (eventType.equals(CacheEntryEventType.ENTRY_UPDATED)) { ((CacheEntryEventListener) listeners[i + 1]).cacheEntryUpdated(event); } else if (eventType.equals(CacheEntryEventType.ENTRY_FLUSHED)) { ((CacheEntryEventListener) listeners[i + 1]).cacheEntryFlushed(event); } else if (eventType.equals(CacheEntryEventType.ENTRY_REMOVED)) { ((CacheEntryEventListener) listeners[i + 1]).cacheEntryRemoved(event); } } } } /** * Dispatch a cache group event to all registered listeners. * * @param eventType The type of event (this is used to branch to the correct method handler) * @param group The cache group that the event applies to * @param origin The origin of this event (optional) */ private void dispatchCacheGroupEvent(CacheEntryEventType eventType, String group, String origin) { CacheGroupEvent event = new CacheGroupEvent(this, group, origin); // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == CacheEntryEventListener.class) { if (eventType.equals(CacheEntryEventType.GROUP_FLUSHED)) { ((CacheEntryEventListener) listeners[i + 1]).cacheGroupFlushed(event); } } } } /** * Dispatch a cache map access event to all registered listeners. * * @param eventType The type of event * @param entry The entry that was affected. * @param origin The origin of this event (optional) */ private void dispatchCacheMapAccessEvent(CacheMapAccessEventType eventType, CacheEntry entry, String origin) { CacheMapAccessEvent event = new CacheMapAccessEvent(eventType, entry, origin); // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == CacheMapAccessEventListener.class) { ((CacheMapAccessEventListener) listeners[i + 1]).accessed(event); } } } /** * Dispatch a cache pattern event to all registered listeners. * * @param eventType The type of event (this is used to branch to the correct method handler) * @param pattern The cache pattern that the event applies to * @param origin The origin of this event (optional) */ private void dispatchCachePatternEvent(CacheEntryEventType eventType, String pattern, String origin) { CachePatternEvent event = new CachePatternEvent(this, pattern, origin); // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == CacheEntryEventListener.class) { if (eventType.equals(CacheEntryEventType.PATTERN_FLUSHED)) { ((CacheEntryEventListener) listeners[i + 1]).cachePatternFlushed(event); } } } } /** * Dispatches a cache-wide event to all registered listeners. * * @param eventType The type of event (this is used to branch to the correct method handler) * @param origin The origin of this event (optional) */ private void dispatchCachewideEvent(CachewideEventType eventType, Date date, String origin) { CachewideEvent event = new CachewideEvent(this, date, origin); // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == CacheEntryEventListener.class) { if (eventType.equals(CachewideEventType.CACHE_FLUSHED)) { ((CacheEntryEventListener) listeners[i + 1]).cacheFlushed(event); } } } } /** * Flush a cache entry. On completion of the flush, a * <tt>CacheEntryEventType.ENTRY_FLUSHED</tt> event is fired. * * @param entry The entry to flush * @param origin The origin of this flush event (optional) */ private void flushEntry(CacheEntry entry, String origin) { String key = entry.getKey(); // Flush the object itself entry.flush(); if (!entry.isNew()) { // Update the entry's state in the map cacheMap.put(key, entry); } // Trigger an ENTRY_FLUSHED event. [CACHE-107] Do this for all flushes. if (listenerList.getListenerCount() > 0) { CacheEntryEvent event = new CacheEntryEvent(this, entry, origin); dispatchCacheEntryEvent(CacheEntryEventType.ENTRY_FLUSHED, event); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?