Java 9 Cleaner正确用法

时间:2018-03-27 10:15:21

标签: java garbage-collection resources

阅读Java 9的Cleaner课程,我在同一页面中找到了这个例子:

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();
        }
    }

在第二行有评论说:

  

清洁工,最好是在图书馆内共享的清洁工

为什么在库中共享一个Cleaner(静态)更可取?

有没有人有关于如何使用Cleaner而不是覆盖finalize()的良好示例?

3 个答案:

答案 0 :(得分:6)

  

为什么在库中有一个共享清理器(静态)更可取?

清洁工有一个关联的线程。线程是有限的本机资源。因此,目标是通过不创建超过必要的更多清洁程序来限制创建的线程数量。

  

有没有人有一个关于如何使用Cleaner而不是覆盖finalize()的好例子?

您发布了参考示例。如果不够,你需要提出更具体的问题。

答案 1 :(得分:1)

文档明确提到:

  

选择新的清洁剂或共享现有的清洁剂由用例决定。

此外:

  

每个清洁工独立运作,管理待处理的[...]

表示在应用程序中允许多个Cleaner个实例。

同样,由于提供了工厂方法Cleaner::create并记录为

  

返回一个新的Cleaner。

我不明白为什么每个应用程序只应该使用一个Cleaner,尽管评论明确说明不是这样。

通过网上冲浪一分钟,我找到了一些示例(例如this article),并且每个static子类都使用了AutoCloseable清洁工。

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

答案 2 :(得分:1)

希望在使用java9时帮助您。

以下代码已经在 Intellij IDEA 2017 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();
        }
    }
}