5 differences between java synchronized and ReentrantLock - Interview Guide

Both synchronized and ReentrantLock in Java are used to achieve thread synchronization, but there are some differences between them.

  1. Usage: synchronized is a keyword in Java that can be used directly in methods or code blocks, while ReentrantLock is a class that requires explicit creation and release of locks.
  2. Reentrant: synchronized is reentrant, which means that a thread can obtain the same lock multiple times, and ReentrantLock is also reentrant, but it requires manually calling the lock() method and unlock() method.
  3. Fairness: synchronized is an unfair lock, that is, the order in which threads acquire locks is uncertain, and ReentrantLock can be set to a fair lock or an unfair lock. By default, it is an unfair lock.
  4. Performance: synchronized is a Java language-level lock, which is implemented by the JVM, while ReentrantLock is implemented based on Java's Lock interface. Performance can be optimized by selecting different implementation classes.
  5. Interruptible waiting: ReentrantLock provides an interruptible lock acquisition method, that is, the tryLock() method. You can try to acquire the lock. If you cannot acquire the lock, you can choose to continue waiting or return false. Here is a simple sample code that demonstrates the use of synchronized and ReentrantLock:
javaCopy codeimport java.util.concurrent.locks.ReentrantLock;
public class SynchronizedVsReentrantLock {
    private static int counter = 0;
    private static Object lock = new Object();
    private static ReentrantLock reentrantLock = new ReentrantLock();
    public static void synchronizedMethod() {
        synchronized (lock) {
            counter++;
        }
    }
    public static void reentrantLockMethod() {
        reentrantLock.lock();
        try {
            counter++;
        } finally {
            reentrantLock.unlock();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        // 使用synchronized
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                synchronizedMethod();
            }
        });
        // 使用ReentrantLock
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                reentrantLockMethod();
            }
        });
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println("counter: " + counter);
    }
}

In the above code, counter is a shared variable, synchronizedMethod() uses the synchronized keyword to synchronize the code block to ensure the atomicity of the operation on counter, and reentrantLockMethod() uses ReentrantLock to achieve the same function. The value of the last output counter should be 2000.

Guess you like

Origin blog.csdn.net/q7w8e9r4/article/details/132533701