1. Introduction of already
ReentrantLock is an implementation of the Lock interface class, which implements AQS through the internal class Sync. Compared with Synchronized, both are reentrant locks, but the difference lies in that ReentrantLock can be more flexible. The locking and unlocking of Synchronized are completed by JVM.
2. Principle of ReetrantLock
2.1 Unfair Lock
Unfair locking is the default way to obtain locks.
Unfair lock When obtaining the synchronization status, the system checks whether the current thread is the thread that acquires the lock. If so, the system increases the synchronization value and returns true, indicating that the synchronization status is successfully obtained.
final boolean nonfairTryAcquire(int acquires) {
// Get the current thread
final Thread current = Thread.currentThread();
// Get the synchronization state of the current thread
int c = getState();
// State 0 indicates that the current lock is not occupied by another thread
if (c == 0) {
// Set the current lock state to acquires
if (compareAndSetState(0, acquires)) {
// Set the current thread to hold an exclusive lock
setExclusiveOwnerThread(current);
return true; }}// Indicates that the current thread is the thread that acquires the lock again
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
Copy the code
2.2 fair lock
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
// The synchronization status of the current thread is 0, trying to acquire the lock
if (c == 0) {
// Check whether there are other threads in the CLH queue. If no current thread succeeds in acquiring the lock, the current thread needs to wait
if(! hasQueuedPredecessors() && compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true; }}else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false; }}Copy the code
The difference between a fair lock and a non-fair lock is that a fair lock determines whether there are other threads in the CLH queue, while a non-fair lock attempts a CAS operation to change the synchronization state.
2.3 Lock Release
The lock is released only when the synchronization status is 0, and all previous operations return false.
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if(Thread.currentThread() ! = getExclusiveOwnerThread())throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
Copy the code
ReentrantLock | Synchronized | |
---|---|---|
Lock implementation mechanism | Rely on AQS | Monitor mode |
flexibility | Supports response interrupts, timeouts, and attempts to acquire locks | inflexible |
Release form | It must appear that unlock() is called to release the lock | Automatic release monitor |
The lock type | Fair locks & Unfair locks | Not fair lock |
Conditions of the queue | Multiple conditional queues can be associated | Associate a conditional queue |
reentrancy | reentrant | reentrant |