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

Reply via email to