Thread Safety
-
Concurrent programming is about *shared, mutable *state.
-
*Atomic **operations: Indivisible set of instructions. Common violations are *read-modify-write *and *check-then-act. Violating it causes race conditions.
-
**Race conditions **means correctness of the computation depends on relative timing of threads.
-
Stateless classes are thread-safe.
-
**AtomicLong **and other lock-free thread-safe classes in java.util.concurrent.atomic package can be used to use common compound operations as atomic. For example, AtomicLong::incrementAndGet method
-
Intrinsic locks **are another method to turn compound operations into atomic. **Synchronized **keyword is used for that. Can be used to lock a block of code, on a non-static method(@GuardedBy(this)), a static method (@GuardedBy(this.getClass())). Essentially they act as **mutexes.
-
Intrinsic locks are reentrant. Means a thread con lock on an object more than once. This lets to call synchronized methods of superclasses. This is different than posix mutexes.
-
When an object is guarded by synchronization, it is important synchronize all accesses including read-only ones.
-
Synchronization is expensive and can reduce performance drastically if used wrong, especially in multi-processor environments. Try to keep synchronized blocks small and non-blocking.