| 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. | |
| ```java | |
| 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`: | |
| ```java | |
| synchronized (Test.class) { | |
| if (!initialized) { | |
| initialize(); | |
| initialized = true; | |
| } | |
| } | |
| ``` | |
| To update a static counter from an instance method, consider using | |
| [`AtomicInteger`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html) | |
| instead of incrementing a static `int` field. |