What are the different ways to achieve synchronization in Java?

Java offers synchronization at several levels of granularity and control, ranging from the built-in synchronized keyword to explicit locks and higher-level coordination utilities in the java.util.concurrent package.

Key Points: • The synchronized keyword, on methods or blocks, is the simplest way to enforce mutual exclusion using an intrinsic lock managed automatically by the JVM. • volatile ensures visibility of a single variable's value across threads, useful for simple flags, though it doesn't provide mutual exclusion. • ReentrantLock and ReadWriteLock offer explicit, more flexible locking with features like tryLock(), timeouts, interruptibility, and fairness policies. • Semaphore controls access to a limited number of permits, useful for bounding concurrent access to a resource pool rather than strict single-thread exclusion. • CountDownLatch and CyclicBarrier coordinate groups of threads around a shared point in time, such as waiting for several tasks to finish before proceeding. • Concurrent collections (ConcurrentHashMap, CopyOnWriteArrayList, BlockingQueue) provide built-in thread safety without requiring the caller to synchronize manually at all.

Example: A producer-consumer pipeline might use a BlockingQueue to hand off work between threads without any manual synchronized blocks, while a resource pool limiting concurrent database connections to ten might use a Semaphore(10) to cap simultaneous access.

Code Example:

Semaphore semaphore = new Semaphore(10);

public void useResource() throws InterruptedException {
    semaphore.acquire();
    try {
        // access limited resource
    } finally {
        semaphore.release();
    }
}

Interview Tip: A concise interview answer is:

"There are several layers available: the synchronized keyword and volatile for basic cases, explicit locks like ReentrantLock for more control, Semaphore for bounding concurrent access, CountDownLatch or CyclicBarrier for coordinating groups of threads, and concurrent collections that are thread-safe by design so you don't need to synchronize around them at all."