Files
Claude 814c32b5ce Add lazy-constants module: LazyConstant (JEP 531) against the holder idiom and double-checked locking
Basics, failure semantics on 26 vs 27, lazy collections, API across 25/26/27, preview-flag traps and a JMH read-path benchmark (jars fetched and sha1-checked, not committed).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01TF9JWFvJSNm6HVzswzZU5a
2026-09-24 12:27:27 +00:00

36 lines
1.5 KiB
Java

// The three classic ways to hold a value that is expensive to build. Plain Java, no preview features.
public class OldWays {
static class Expensive {
final String how;
Expensive(String how) { this.how = how; System.out.println(" [init] building Expensive via " + how); }
}
// 1. Eager: built when OldWays is initialised, which is before main runs, whether or not anyone uses it.
static final Expensive EAGER = new Expensive("eager static final");
// 2. Holder idiom: the JVM initialises Holder the first time it is touched, and does so exactly once.
static class Holder { static final Expensive VALUE = new Expensive("holder idiom"); }
static Expensive holder() { return Holder.VALUE; }
// 3. Double-checked locking: correct only because the field is volatile.
private static volatile Expensive dcl;
static Expensive doubleChecked() {
Expensive local = dcl;
if (local == null) {
synchronized (OldWays.class) {
local = dcl;
if (local == null) dcl = local = new Expensive("double-checked locking");
}
}
return local;
}
public static void main(String[] args) {
System.out.println("main starts (the eager value already exists)");
System.out.println("first holder() call:"); holder();
System.out.println("second holder() call:"); holder();
System.out.println("first doubleChecked() call:"); doubleChecked();
System.out.println("second doubleChecked() call:"); doubleChecked();
}
}