Sobes.tech
Middle

What are the differences between synchronized and ReentrantLock?

sobes.tech AI

Answer from AI

  • synchronized is a language keyword. ReentrantLock is a class from the java.util.concurrent.locks package.
  • synchronized can be used to lock methods or blocks of code. ReentrantLock locks only code blocks through the lock() and unlock() methods.
  • synchronized is a primitive form of locking, lacking fine-tuning capabilities. ReentrantLock offers more flexibility:
    • Ability to interrupt a blocked thread (lockInterruptibly()).
    • Attempt non-blocking lock (tryLock()).
    • Set a timeout for lock attempts (tryLock(long timeout, TimeUnit unit)).
    • Create multiple condition variables (newCondition()).
  • synchronized automatically releases the lock when exiting the locked block (including when exceptions occur). ReentrantLock requires explicit unlock() calls in a finally block to avoid deadlocks.
  • The performance of ReentrantLock can be higher under high thread contention compared to synchronized (though in recent Java versions, differences may be minimal).
  • ReentrantLock supports a fair mode, where threads acquire the lock in request order. synchronized does not guarantee fairness.

Example of using ReentrantLock:

import java.util.concurrent.locks.ReentrantLock;

public class SharedResource {

    private final ReentrantLock lock = new ReentrantLock();
    private int counter = 0;

    public void increment() {
        lock.lock(); // Acquire the lock
        try {
            counter++;
            System.out.println(Thread.currentThread().getName() + " incremented counter to " + counter);
        } finally {
            lock.unlock(); // Release the lock in finally block
        }
    }

    public int getCounter() {
        return counter; // Read without locking (if read synchronization is not required)
    }
}

Example of using synchronized:

public class SharedResourceSynchronized {

    private int counter = 0;

    public synchronized void increment() { // Lock on method
        counter++;
        System.out.println(Thread.currentThread().getName() + " incremented counter to " + counter);
    }

    public int getCounter() {
        return counter;
    }
}