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)
| 62 | |
| 63 | |
| 64 | public static void startFinalizer(Class<?> finalizableReferenceClass, ReferenceQueue<Object> queue, 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 | Finalizer finalizer = new Finalizer(finalizableReferenceClass, queue, frqReference); |
| 77 | Thread thread = new Thread(finalizer); |
| 78 | thread.setName(Finalizer.class.getName()); |
| 79 | thread.setDaemon(true); |
| 80 | try { |
| 81 | if (inheritableThreadLocals != null) { |
| 82 | inheritableThreadLocals.set(thread, null); |
| 83 | } |
| 84 | } catch (Throwable t) { |
| 85 | logger.log( |
| 86 | Level.INFO, |
| 87 | "Failed to clear thread local values inherited by reference finalizer thread.", |
| 88 | t); |
| 89 | } |
| 90 | thread.start(); |
| 91 | } |
| 92 | |
| 93 | private final WeakReference<Class<?>> finalizableReferenceClassReference; |
| 94 |