This is a cliche, but if it were just the more common ones, I wouldn’t need to record this article, and there’s a subtle difference today when writing code for both.
Conventional difference
- ReentrantLock is more flexible, providing timeout acquisition locks that can be broken. Provides both unfair and unfair locks, while synchronized is merely unfair locks.
- In usage, ReentrantLock must release the lock manually and can only modify code blocks. Synchronized, on the other hand, does not release the lock manually and can otherwise modify methods.
Another difference is that synchronized threads are blocked, whereas ReentrantLock threads are in a waiting state
Doubt point
Is ReentrantLock really better than synchronized?
I wrote a simple demo
public class LockDemo {
static ReentrantLock lock = new ReentrantLock(false); public static void main(String[] args) { syncTest(); // lockTest(); } public static voidsyncTest() {
for (int i = 0; i < 10; i++) {
new Thread() {
@Override
public void run() {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + "Start locking");
try {
Thread.sleep(2 * 1000);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + "Unlocked");
}
}
}
}.start();
}
}
public static void lockTest() {
for (int i = 0; i < 10; i++) {
new Thread() {
@Override
public void run() {
lock.lock();
System.out.println(Thread.currentThread().getName() + "Start locking");
try {
Thread.sleep(2 * 1000);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + "Unlocked"); lock.unlock(); } } }.start(); }}}Copy the code
The results are as follows:
Synchonized, the thread states are only time_waiting and blocked. When the thread that acquired the lock completes execution, the other threads will fight for the lock again together
ReentrantLock’s unfair lock test, even though I’m using an unfair lock, looks fair. The internal thread is in a waiting state
As for whether the performance is high, I think the performance of acquiring a lock by a single thread is higher than that by multiple threads. The optimization made by synchronized lock is only made by a single thread or two threads, and once upgraded to a heavyweight lock, those optimizations are no longer effective.
This is a personal guess, of course.
The last
Look at the source code inside ReentrantLock to see the details.
- Locksupport.park, the thread will enter the waiting state
- ReentrantLock uses an unfair lock, but if a new thread attempts to acquire the lock, only the current thread will fight for it.