001
014
015 package com.liferay.portal.kernel.memory;
016
017 import java.lang.ref.Reference;
018 import java.lang.ref.ReferenceQueue;
019
020 import java.util.Map;
021 import java.util.concurrent.ConcurrentHashMap;
022
023
026 public class FinalizeManager {
027
028 public static final boolean THREAD_ENABLED = Boolean.getBoolean(
029 FinalizeManager.class.getName() + ".thread.enabled");
030
031 public static <T> Reference<T> register(
032 T realReference, FinalizeAction finalizeAction) {
033
034 Reference<T> reference = new EqualityWeakReference<T>(
035 realReference, _referenceQueue);
036
037 _referenceActionMap.put(reference, finalizeAction);
038
039 if (!THREAD_ENABLED) {
040 _pollingCleanup();
041 }
042
043 return reference;
044 }
045
046 private static void _pollingCleanup() {
047 Reference<? extends Object> reference = null;
048
049 while ((reference = _referenceQueue.poll()) != null) {
050 FinalizeAction finalizeAction = _referenceActionMap.remove(
051 reference);
052
053 finalizeAction.doFinalize();
054 }
055 }
056
057 private static Map<Reference<?>, FinalizeAction> _referenceActionMap =
058 new ConcurrentHashMap<Reference<?>, FinalizeAction>();
059 private static ReferenceQueue<Object> _referenceQueue =
060 new ReferenceQueue<Object>();
061
062 private static class FinalizeThread extends Thread {
063
064 public FinalizeThread(String name) {
065 super(name);
066 }
067
068 @Override
069 public void run() {
070 while (true) {
071 try {
072 Reference<? extends Object> reference =
073 _referenceQueue.remove();
074
075 FinalizeAction finalizeAction = _referenceActionMap.remove(
076 reference);
077
078 finalizeAction.doFinalize();
079 }
080 catch (InterruptedException ie) {
081 }
082 }
083 }
084 }
085
086 static {
087 if (THREAD_ENABLED) {
088 Thread thread = new FinalizeThread("Finalize Thread");
089
090 thread.setContextClassLoader(
091 FinalizeManager.class.getClassLoader());
092
093 thread.setDaemon(true);
094
095 thread.start();
096 }
097 }
098
099 }