Working with Synchronization

1. Using synchronized Keyword

Example: synchronized

public synchronized void increment() { count++; }    // intrinsic lock on this

public void update() {
    synchronized (lock) { ... }                      // explicit lock object
}
FormLock
Instance methodthis
Static methodClass object
BlockSpecified object

2. Synchronizing Methods

AspectDetail
GranularityWhole method body
Visibilitypublic synchronized exposes lock to outside (avoid)

3. Synchronizing Blocks

PracticeDetail
Private lockprivate final Object lock = new Object();
Minimize scopeHold for shortest possible time

4. Understanding Intrinsic Locks (Monitor)

PropertyDetail
ReentrantSame thread can re-acquire
Mutual exclusionOnly one thread holds lock
VisibilityEstablishes happens-before

5. Using Lock Interface

Example: Lock

private final Lock lock = new ReentrantLock();
public void update() {
    lock.lock();
    try { ... } finally { lock.unlock(); }
}
MethodUse
lock()Block until acquired
tryLock() / tryLock(t, u)Non-blocking / timed
lockInterruptibly()Responds to interruption
unlock()Always in finally

6. Using ReentrantLock

FeatureDetail
Fairnessnew ReentrantLock(true) = FIFO
Hold countgetHoldCount()
ConditionsnewCondition()

7. Using ReadWriteLock

AspectDetail
Reads concurrentMultiple readers OK if no writer
Writes exclusiveOne writer, no readers
Best forRead-heavy workloads
Modern alternativeStampedLock with optimistic reads

8. Using StampedLock JAVA 8+

Example: Optimistic read

StampedLock sl = new StampedLock();
long stamp = sl.tryOptimisticRead();
double curX = x, curY = y;
if (!sl.validate(stamp)) {
    stamp = sl.readLock();
    try { curX = x; curY = y; } finally { sl.unlockRead(stamp); }
}
ModeDetail
WriteExclusive
ReadShared
Optimistic readNo lock; validate after
LimitationNot reentrant

9. Using volatile Keyword

GuaranteeDetail
VisibilityWrites visible to other threads
OrderingPrevents reordering across volatile access
No atomicity++ still NOT atomic on volatile
Use caseStatus flags, double-checked locking

10. Understanding Atomic Operations

ClassUse
AtomicInteger / Long / BooleanAtomic primitives
AtomicReference<T>Atomic object reference
AtomicIntegerArrayElement-wise atomic
OperationsincrementAndGet, compareAndSet, updateAndGet
High contentionUse LongAdder/LongAccumulator instead

11. Using Atomic Classes

Example: Atomic counter

AtomicLong counter = new AtomicLong();
counter.incrementAndGet();
counter.compareAndSet(10, 20);    // CAS
counter.updateAndGet(v -> v * 2);

LongAdder hits = new LongAdder();    // better under high contention
hits.increment();
long total = hits.sum();
ClassWhen
AtomicLongLow/medium contention
LongAdderHigh write contention; eventual consistent reads
LongAccumulatorCustom merge function

12. Avoiding Deadlocks

StrategyDetail
Lock orderingAlways acquire in same global order
Use tryLock with timeoutBack off and retry
Avoid nested locksHold one at a time
Detectionjstack shows deadlock

13. Understanding Memory Model (JMM)

ConceptDetail
Happens-beforeOrdering guarantee for visibility
Synchronization actionsLock/unlock, volatile read/write, thread start/join
Final fieldsSafely published if not exposed before constructor finishes
No JMM violation toolsJCStress for testing