FileInputStream and FileOutputStream use ThreadLocal to communicate
information from finalize() to close(). This is slow and ugly.
Generally, use of ThreadLocal is considered a last resource.
Here's a code sketch of a cleaner solution:
Instead of
private final Object closeLock = new Object();
private volatile boolean closed = false;
private static final ThreadLocal<Boolean> runningFinalize =
use
private final static int OPEN = 0;
private final static int RUNNING_FINALIZE = 1;
private final static int CLOSED = 2;
AtomicInteger state = new AtomicInteger(OPEN);
and then CAS state in an infinite loop in the state-changing methods.
e.g.
void close() {
for (;;) {
int st = state.get();
if (st == CLOSED) return;
boolean runningFinalize = (st == RUNNING_FINALIZE);
...
if (state.compareAndSetState(st, CLOSED)).... return;
}
}
This does not require locking to manage state transitions.