1 16 17 package org.springframework.util; 18 19 import java.lang.ref.Reference ; 20 import java.lang.ref.ReferenceQueue ; 21 import java.lang.ref.WeakReference ; 22 import java.util.Collections ; 23 import java.util.HashMap ; 24 import java.util.Map ; 25 26 import org.apache.commons.logging.Log; 27 import org.apache.commons.logging.LogFactory; 28 29 49 public class WeakReferenceMonitor { 50 51 private static final Log logger = LogFactory.getLog(WeakReferenceMonitor.class); 52 53 private static final ReferenceQueue handleQueue = new ReferenceQueue (); 55 56 private static final Map trackedEntries = Collections.synchronizedMap(new HashMap ()); 58 59 private static Thread monitoringThread = null; 61 62 63 69 public static void monitor(Object handle, ReleaseListener listener) { 70 if (logger.isDebugEnabled()) { 71 logger.debug("Monitoring handle [" + handle + "] with release listener [" + listener + "]"); 72 } 73 74 WeakReference weakRef = new WeakReference (handle, handleQueue); 77 78 addEntry(weakRef, listener); 80 } 81 82 88 private static void addEntry(Reference ref, ReleaseListener entry) { 89 trackedEntries.put(ref, entry); 91 92 synchronized (WeakReferenceMonitor.class) { 94 if (!isMonitoringThreadRunning()) { 95 monitoringThread = new Thread (new MonitoringProcess(), WeakReferenceMonitor.class.getName()); 96 monitoringThread.setDaemon(true); 97 monitoringThread.start(); 98 } 99 } 100 } 101 102 107 private static ReleaseListener removeEntry(Reference reference) { 108 return (ReleaseListener) trackedEntries.remove(reference); 109 } 110 111 114 private static boolean isMonitoringThreadRunning() { 115 synchronized (WeakReferenceMonitor.class) { 116 return (monitoringThread != null); 117 } 118 } 119 120 121 124 private static class MonitoringProcess implements Runnable { 125 126 public void run() { 127 logger.debug("Starting reference monitor thread"); 128 try { 129 while (!trackedEntries.isEmpty()) { 131 try { 132 Reference reference = handleQueue.remove(); 133 ReleaseListener entry = removeEntry(reference); 135 if (entry != null) { 136 entry.released(); 138 } 139 } 140 catch (InterruptedException ex) { 141 logger.debug("Reference monitor thread interrupted", ex); 142 break; 143 } 144 } 145 } 146 finally { 147 logger.debug("Stopping reference monitor thread"); 148 synchronized (WeakReferenceMonitor.class) { 149 monitoringThread = null; 150 } 151 } 152 } 153 } 154 155 156 160 public static interface ReleaseListener { 161 162 166 void released(); 167 } 168 169 } 170 | Popular Tags |