Java : Cleaner with Examples

Cleaner (Java SE 18 & JDK 18) API Examples.
You will find code examples on most Cleaner methods.


Summary

Cleaner manages a set of object references and corresponding cleaning actions.

Class diagram

class Foo {
    @SuppressWarnings("removal")
    @Override
    protected void finalize() {
        System.out.println("Finalize!");
    }
}

var foo = new Foo();

final var cleaner = Cleaner.create();

cleaner.register(foo, () -> {
    System.out.println("Clean!");

    final var current = Thread.currentThread();
    System.out.printf("  (thread id = %d, daemon = %b)%n", current.getId(), current.isDaemon());
});

System.out.println("-- start -- (thread id = " + Thread.currentThread().getId() + ")");

foo = null;

System.out.println("-- gc --");
System.gc();

TimeUnit.SECONDS.sleep(3);
System.out.println("-- sleep --");

System.out.println("-- gc --");
System.gc();

TimeUnit.SECONDS.sleep(3);
System.out.println("-- sleep --");

// Result
// ↓
//-- start -- (thread id = 1)
//-- gc --
//Finalize!
//-- sleep --
//-- gc --
//Clean!
//  (thread id = 19, daemon = true)
//-- sleep --

Methods

static Cleaner create ()

Returns a new Cleaner.

class Foo {
    @SuppressWarnings("removal")
    @Override
    protected void finalize() {
        System.out.println("Finalize!");
    }
}

var foo = new Foo();

final var cleaner = Cleaner.create();

cleaner.register(foo, () -> {
    System.out.println("Clean!");

    final var current = Thread.currentThread();
    System.out.printf("  (thread id = %d, daemon = %b)%n", current.getId(), current.isDaemon());
});

System.out.println("-- start -- (thread id = " + Thread.currentThread().getId() + ")");

foo = null;

System.out.println("-- gc --");
System.gc();

TimeUnit.SECONDS.sleep(3);
System.out.println("-- sleep --");

System.out.println("-- gc --");
System.gc();

TimeUnit.SECONDS.sleep(3);
System.out.println("-- sleep --");

// Result
// ↓
//-- start -- (thread id = 1)
//-- gc --
//Finalize!
//-- sleep --
//-- gc --
//Clean!
//  (thread id = 19, daemon = true)
//-- sleep --

static Cleaner create (ThreadFactory threadFactory)

Returns a new Cleaner using a Thread from the ThreadFactory.

class Foo {
    @SuppressWarnings("removal")
    @Override
    protected void finalize() {
        System.out.println("Finalize!");
    }
}

var foo = new Foo();

final var cleaner = Cleaner.create(r -> new Thread(r, "ABC"));

cleaner.register(foo, () -> {
    System.out.println("Clean!");

    final var current = Thread.currentThread();
    System.out.printf("  (thread id = %d, name = %s, daemon = %b)%n",
            current.getId(), current.getName(), current.isDaemon());
});

System.out.println("-- start -- (thread id = " + Thread.currentThread().getId() + ")");

foo = null;

System.out.println("-- gc --");
System.gc();

TimeUnit.SECONDS.sleep(3);
System.out.println("-- sleep --");

System.out.println("-- gc --");
System.gc();

TimeUnit.SECONDS.sleep(3);
System.out.println("-- sleep --");

// Result
// ↓
//-- start -- (thread id = 1)
//-- gc --
//Finalize!
//-- sleep --
//-- gc --
//Clean!
//  (thread id = 19, name = ABC, daemon = true)
//-- sleep --

Cleaner.Cleanable register (Object obj, Runnable action)

Registers an object and a cleaning action to run when the object becomes phantom reachable.

class Foo {
}

final var foo = new Foo();
final var cleaner = Cleaner.create();

final var cleanable = cleaner.register(foo, () -> {
    System.out.println("Clean!");

    final var current = Thread.currentThread();
    System.out.printf("  (thread id = %d, daemon = %b)%n", current.getId(), current.isDaemon());
});

System.out.println("-- start -- (thread id = " + Thread.currentThread().getId() + ")");

cleanable.clean();

// Result
// ↓
//-- start -- (thread id = 1)
//Clean!
//  (thread id = 1, daemon = false)

Related posts

To top of page