| Thread-safe methods should never be overridden by methods that are not |
| thread-safe. Doing so violates behavioural subtyping, and can result in bugs if |
| the subtype is used in contexts that rely on the thread-safety of the supertype. |
| |
| Overriding a `synchronized` method with a method that is not `synchronized` can |
| be a sign that the thread-safety of the supertype is not being preserved. |
| |
| ```java |
| class Counter { |
| private int count = 0; |
| |
| synchronized void increment() { |
| count++; |
| } |
| } |
| ``` |
| |
| ```java |
| // MyCounter is not thread safe! |
| class MyCounter extends Counter { |
| private int count = 0; |
| |
| void increment() { |
| count++; |
| } |
| } |
| ``` |
| |
| Note that there are many ways to implement a thread-safe method without using |
| the `synchronized` modifier (e.g. `synchronized` statements using explicit |
| locks, or other locking constructs). When overriding a `synchronized` method |
| with a method that is thread-safe but does not have the `synchronized` modifier, |
| consider adding `@SuppressWarnings("UnsynchronizedOverridesSynchronized")` and |
| an explanation. |
| |
| ```java |
| class MyCounter extends Counter { |
| private AtomicInteger count = AtomicInteger(); |
| |
| @SuppressWarnings("UnsynchronizedOverridesSynchronized") // AtomicInteger is thread-safe |
| void increment() { |
| count.getAndIncrement(); |
| } |
| } |
| ``` |