Lazy Initialization of Static Field Without Synchronization
ID |
java.lazy_init_static |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Java |
Tags |
CWE:362, concurrency, reliability |
Description
Reports lazy initialization of a static field in an unsynchronized context. The pattern if (field == null) { field = new …; } outside a synchronized block is a race condition: multiple threads can simultaneously see null, create separate instances, and silently discard all but one.
Rationale
Static fields are shared across all threads. Without synchronization, there is no happens-before relationship between the null check and the assignment, so the field may be initialized multiple times. If the initialization has side effects (e.g., opening a connection, registering a resource), the duplicates cause resource leaks.
// Bad -- race condition
private static Connection conn;
public static Connection getConnection() {
if (conn == null) {
conn = createConnection();
}
return conn;
}
Remediation
Use a synchronized method, the holder-class idiom, or volatile double-checked locking:
// Good -- synchronized
public static synchronized Connection getConnection() {
if (conn == null) {
conn = createConnection();
}
return conn;
}
// Better -- holder class
private static class Holder {
static final Connection INSTANCE = createConnection();
}
public static Connection getConnection() {
return Holder.INSTANCE;
}