RFR JDK-8185582, Update Zip implementation to use Cleaner, not finalizers

Peter Levart peter.levart at gmail.com
Mon Oct 30 20:49:42 UTC 2017


Hi again,

On 10/30/17 21:34, Peter Levart wrote:
> To mimic the finalization registration, it might be a good to 
> encourage the following coding pattern (using Inflater/ZStreamRef just 
> as an example, not suggesting to do that here unless you like it):
>
> class ZStreamRef implements Runnable {
>
>     private final LongConsumer end;
>     private volatile long address;
>     final Cleaner.Cleanable cleanable; // move cleanable from 
> Inflater/Deflater to here
>
>     ZStreamRef (Object reference, LongSupplier init, LongConsumer end) {
>         // perform registration as 1st thing in constructor
>         cleanable = CleanerFactory.cleaner().register(reference, this);
>         this.end = end;
>         this.address = init.getAsLong();
>     }
>
>     long address() {
>         return address;
>     }
>
>     public synchronized void run() {
>         long addr = address;
>         address = 0;
>         if (addr != 0) {
>             end.accept(addr);
>         }
>     }
> }

...above example lends itself as a use case for the following equivalent 
alternative using internal low-level API where ZStreamRef becomes the 
Cleanable itself:

class ZStreamRef extends PhantomCleanable<Object> {

     private final LongConsumer end;
     private volatile long address;

     ZStreamRef (Object referent, LongSupplier init, LongConsumer end) {
         // here the registration MUST happen as 1st thing - enforced by 
javac
         super(referent, CleanerFactory.cleaner());
         this.end = end;
         this.address = init.getAsLong();
     }

     long address() {
         return address;
     }

     @Override
     protected void performCleanup() {
         long addr = address;
         address = 0;
         if (addr != 0) {
             end.accept(addr);
         }
     }
}


Inflater/Deflater constructor is unchanged while end() becomes:

      public void end() {
         synchronized (zsRef) {
             zsRef.clean(); // zsRef is-a Cleanable
             buf = null;
         }
     }


It's interesting that something that is considered a "low-level" API in 
above example forces you to do it right, while the high level API doesn't.

Regards, Peter



More information about the core-libs-dev mailing list