Java9清洁剂的正确用法

Java9清洁剂的正确用法,java,garbage-collection,resources,Java,Garbage Collection,Resources,在阅读Java 9的类时,我在同一页中发现了以下示例: 公共类清理示例实现自动关闭{ //清洁剂,最好是在图书馆内共享的清洁剂 专用静电最终清洁剂=; 静态类状态实现可运行{ 国家(……){ //初始化清理操作所需的状态 } 公开募捐{ //正在访问状态的清理操作,最多执行一次 } } 私人最终国家; 私人最终清洁剂。可清洁 公共清洁示例(){ this.state=新状态(…); this.cleanable=cleaner.register(this,state); } 公众假期结束(){

在阅读Java 9的类时,我在同一页中发现了以下示例:

公共类清理示例实现自动关闭{
//清洁剂,最好是在图书馆内共享的清洁剂
专用静电最终清洁剂=;
静态类状态实现可运行{
国家(……){
//初始化清理操作所需的状态
}
公开募捐{
//正在访问状态的清理操作,最多执行一次
}
}
私人最终国家;
私人最终清洁剂。可清洁
公共清洁示例(){
this.state=新状态(…);
this.cleanable=cleaner.register(this,state);
}
公众假期结束(){
干净的;干净的;
}
}
第二行有一条评论说:

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

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


关于如何使用
Cleaner
而不是覆盖
finalize()
,有谁有好的例子吗?

文档确实明确提到:

新清洁剂或共享现有清洁剂的选择取决于用例

此外:

每个清洁器独立运行,管理待定[…]

这意味着一个应用程序中允许有多个
Cleaner
实例

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

返回一个新的清洁器

我不明白为什么每个应用程序只能使用一个
清理器
,尽管评论中明确指出不是这样


通过上网一分钟,我找到了一些示例(例如),并且所有示例都为每个
AutoCloseable
子类使用
static
清洁器

private final static Cleaner cleaner = Cleaner.create();
为什么在库中有一个共享清理器(静态)更可取

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

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


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

希望它能帮助你使用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();
        }
    }
}

这就是我想了解的。因此,与终结块不同,开发人员可以控制
线程
,在该线程中运行
清理程序
。@M.S.还有更多。请注意,
CleaningExample
实现了
AutoCloseable
,因此可以在
try(…)
语句中使用。如果您使用它,则会在块的末尾立即进行清理,而垃圾收集器将变得无关紧要。这与不能取消的
finalize()
不同,因此在使用
finalize()
时,您必须接受这样一个事实:对象需要收集两次,一次是在
finalize()
之前,一次是在使用资源的代码调用
close()之后,即使无事可做,也要收集一次
。我还怀疑在本例中,
Cleaner
的行为类似于计划B。请提供一些解释说明:这正是您不应该编写的代码类型。这里的匿名类可以保留对其外部类的引用,导致它永远不会被清理。它在这里工作的唯一原因是匿名类是在
静态方法中创建的。例如,如果您在构造函数中执行此操作,这将根本不起作用。