RFR 9: 8138696 : java.lang.ref.Cleaner - an easy to use alternative to finalization
Roger Riggs
Roger.Riggs at oracle.com
Tue Dec 8 20:01:17 UTC 2015
Hi Peter,
Tricky indeed, the visibility of what is captured is too subtle.
Even if the field is final, it captures this, not the value.
I suppose it is more efficient not to copy field values.
But other than recommending capturing only local variables and arguments,
is there any other relevant advice?
I added examples of both nested class based and lambda based cleaners to the
Cleaner javadoc in the @apiNote.
[1]http://cr.openjdk.java.net/~rriggs/webrev-cleaner-8138696/
[2]http://cr.openjdk.java.net/~rriggs/cleaner-doc/index.html
Thanks, Roger
On 12/08/2015 01:51 PM, Peter Levart wrote:
>
>
> On 12/08/2015 04:34 PM, Roger Riggs wrote:
>> Hi Peter,
>>
>> Thanks for the example and explanations.
>>
>> For simple cleanup of specific state values, I probably would have
>> used lambda instead of an explicit
>> inner class but both styles use the same mechanism.
>> The point about using a shared cleaner can be reinforced in the
>> example too.
>>
>> public static class CleanerExample implements AutoCloseable {
>>
>> FileDescriptor fd = ...;
>>
>> private static final Cleaner cleaner = Cleaner.create();
>>
>> private final Cleaner.Cleanable cleanable =
>> cleaner.register(this, () -> fd.close());
>>
>> @Override
>> public void close() {
>> cleanable.clean();
>> }
>> }
>>
>
> Sorry Roger, but this example is flawed. This is tricky! The lambda
> "() -> fd.close()" captures 'this', not only 'fd' as can be seen by
> running the following example:
>
> public class Test {
>
> int x = 0;
>
> final IntSupplier xSupplier = () -> x;
>
> public static void main(String[] args) {
> Test t = new Test();
> System.out.println(t.xSupplier.getAsInt());
> t.x = 12;
> System.out.println(t.xSupplier.getAsInt());
> }
> }
>
> ...which prints:
>
> 0
> 12
>
>
> To correct that, but still use lambda, you would have to capture a
> local variable, like:
>
> public class Test {
>
> int x = 0;
>
> final IntSupplier xSupplier;
>
> {
> int xValue = x;
> xSupplier = () -> xValue;
> }
>
> public static void main(String[] args) {
> Test t = new Test();
> System.out.println(t.xSupplier.getAsInt());
> t.x = 12;
> System.out.println(t.xSupplier.getAsInt());
> }
> }
>
>
> ...now prints:
>
> 0
> 0
>
>
> Regards, Peter
>
>>
More information about the core-libs-dev
mailing list