Starts the Finalizer thread. FinalizableReferenceQueue calls this method reflectively. @param finalizableReferenceClass FinalizableReference.class. @param queue a reference queue that the thread will poll. @param frqReference a phantom reference to the FinalizableReferenceQueue, which will be queue
(
Class<?> finalizableReferenceClass,
ReferenceQueue<Object> queue,
PhantomReference<Object> frqReference)
| 59 | * close() method is called. |
| 60 | */ |
| 61 | public static void startFinalizer( |
| 62 | Class<?> finalizableReferenceClass, |
| 63 | ReferenceQueue<Object> queue, |
| 64 | PhantomReference<Object> frqReference) { |
| 65 | /* |
| 66 | * We use FinalizableReference.class for two things: |
| 67 | * |
| 68 | * 1) To invoke FinalizableReference.finalizeReferent() |
| 69 | * |
| 70 | * 2) To detect when FinalizableReference's class loader has to be garbage collected, at which |
| 71 | * point, Finalizer can stop running |
| 72 | */ |
| 73 | if (!finalizableReferenceClass.getName().equals(FINALIZABLE_REFERENCE)) { |
| 74 | throw new IllegalArgumentException("Expected " + FINALIZABLE_REFERENCE + "."); |
| 75 | } |
| 76 | |
| 77 | Finalizer finalizer = new Finalizer(finalizableReferenceClass, queue, frqReference); |
| 78 | Thread thread = new Thread(finalizer); |
| 79 | thread.setName(Finalizer.class.getName()); |
| 80 | thread.setDaemon(true); |
| 81 | try { |
| 82 | if (inheritableThreadLocals != null) { |
| 83 | inheritableThreadLocals.set(thread, null); |
| 84 | } |
| 85 | } catch (Throwable t) { |
| 86 | logger.log( |
| 87 | Level.INFO, |
| 88 | "Failed to clear thread local values inherited by reference finalizer thread.", |
| 89 | t); |
| 90 | } |
| 91 | thread.start(); |
| 92 | } |
| 93 | |
| 94 | private final WeakReference<Class<?>> finalizableReferenceClassReference; |
| 95 | private final PhantomReference<Object> frqReference; |