Protecting writes to a static field by synchronizing on an instance lock is not thread-safe.
In the following example, two difference instances of Test
can each acquire
their own instance lock and call initialize()
at the same time.
class Test {
private final Object lock = new Object();
static initialized = false;
static void initialize() { /* ... */ }
Test() {
synchronized (lock) {
if (!initialized) {
initialize();
// error: modification of static variable guarded by instance variable 'lock'
initialized = true;
}
// ...
}
}
}
Static fields should generally be guarded by static locks, and instance fields guarded by instance locks.
The example above could be made thread-safe by locking on the enclosing Class
:
synchronized (Test.class) {
if (!initialized) {
initialize();
initialized = true;
}
}
To update a static counter from an instance method, consider using
AtomicInteger
instead of incrementing a static int
field.
Suppress false positives by adding the suppression annotation @SuppressWarnings("StaticGuardedByInstance")
to the enclosing element.