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;
}