@@ -58,17 +58,27 @@ private Cleaner() {
5858 cleanerRunning = new AtomicBoolean (false );
5959 }
6060
61- public Cleanable register (Object obj , Runnable cleanupTask ) {
61+ public Cleanable register (Object referent , Runnable cleanupTask ) {
6262 // The important side effect is the PhantomReference, that is yielded
6363 // after the referent is GCed
64- Cleanable cleanable = add (new CleanerRef (obj , referenceQueue , cleanupTask ));
64+ Cleanable cleanable = add (new CleanerRef (referent , referenceQueue , cleanupTask ));
6565
6666 if (cleanerRunning .compareAndSet (false , true )) {
6767 Logger .getLogger (Cleaner .class .getName ()).log (Level .FINE , "Starting CleanerThread" );
6868 Thread cleanerThread = new CleanerThread ();
6969 cleanerThread .start ();
7070 }
7171
72+ // NOTE: This is a "pointless" check in the conventional sense, however it serves to guarantee that the
73+ // referent is not garbage collected before the CleanerRef is fully constructed which can happen due
74+ // to reordering of instructions by the compiler or the CPU. In Java 9+ Reference.reachabilityFence() was
75+ // introduced to provide this guarantee, but we want to stay compatible with Java 8, so this is the common
76+ // idiom to achieve the same effect, by ensuring that the referent is still strongly reachable at
77+ // this point.
78+ if (referent == null ) {
79+ throw new IllegalArgumentException ("The referent object must not be null" );
80+ }
81+
7282 return cleanable ;
7383 }
7484
@@ -83,13 +93,12 @@ private void remove(final CleanerRef node) {
8393 }
8494
8595 private static class CleanerRef extends PhantomReference <Object > implements Cleanable {
86- private final Runnable cleanupTask ;
87- private final AtomicBoolean cleaned ;
96+ private volatile Runnable cleanupTask ;
97+ private AtomicBoolean cleaned = new AtomicBoolean ( false ) ;
8898
8999 CleanerRef (Object referent , ReferenceQueue <? super Object > q , Runnable cleanupTask ) {
90100 super (referent , q );
91101 this .cleanupTask = cleanupTask ;
92- this .cleaned = new AtomicBoolean (false );
93102 }
94103
95104 @ Override
0 commit comments