简体   繁体   中英

Java 9 Cleaner Correct Usage

Reading about Java 9's Cleaner class, I found this example in the same page:

public class CleaningExample implements AutoCloseable {
    // A cleaner, preferably one shared within a library
    private static final Cleaner cleaner = <cleaner>;

    static class State implements Runnable {

        State(...) {
            // initialize State needed for cleaning action
        }

        public void run() {
            // cleanup action accessing State, executed at most once
        }
    }

    private final State;
    private final Cleaner.Cleanable cleanable

    public CleaningExample() {
        this.state = new State(...);
        this.cleanable = cleaner.register(this, state);
    }

    public void close() {
        cleanable.clean();
    }
}

In the second line there is a comment saying:

A cleaner, preferably one shared within a library

Why is it preferable to have one shared Cleaner (static) within a library?

Does anybody have a good example about how to use Cleaner instead of overriding finalize() ?

Why is it preferable to have one shared Cleaner (static) within a library?

A cleaner has an associated thread. Threads are limited native resources. So the goal is to limit the amount of Threads created by not creating more cleaners than necessary.

Does anybody have a good example about how to use Cleaner instead of overriding finalize()?

You posted the reference example. You need to ask more specific questions if that is insufficient.

The docs do explicitly mention:

The choice of a new cleaner or sharing an existing cleaner is determined by the use case.

Also:

Each cleaner operates independently, managing the pending [...]

which implies multiple Cleaner instances are allowed within an application.

Again, since the factory method Cleaner::create is provided and is documented as

Returns a new Cleaner.

I do not see why only one Cleaner per application should be used, although the comment definitely states otherwise.


By surfing the web for a minute I found a few examples ( eg this article ), and all use a static Cleaner for each AutoCloseable sub-class.

private final static Cleaner cleaner = Cleaner.create();

Hope it help you if using java9.

The code below was already tested in Intellij IDEA 2017 and oracle jdk 9 .

import java.lang.ref.Cleaner;

public class Main {

    public Main() {

    }

    public static void main(String[] args) {
        System.out.println("Hello World!");

        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Cleaner cleaner = Cleaner.create();
            Main obj = new Main();
            cleaner.register(obj, new Runnable() {
                @Override
                public void run() {
                    System.out.println("Hello World!222");
                }
            });
            System.gc();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM