Explicit locks in Java multithreading

Posted May 28, 20203 min read

1 . Interface method display

//Lock interface:java.util.concurrent.locks.Lock
public interface Lock {
    void lock();

    void lockInterruptibly() throws InterruptedException;

    boolean tryLock();

    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;


    void unlock();

    Condition newCondition();
}

2 . Method analysis

The above 6 methods are the methods that the Lock interface needs to implement. The most commonly used implementation class in Lock is ReentrantLock. Only the methods related to the locking operation are analyzed and differentiated here.

  • void lock():When the lock is idle, the current thread immediately acquires the lock; when the lock is occupied by another thread, the current thread enters the blocking waiting schedule and finally acquires the lock. This method is functionally closest to the synchronized keyword. Can block but not respond to thread interruptions.
  • void lockInterruptibly() throws InterruptedException:When the lock is idle, the current thread immediately acquires the lock; when the lock is occupied by another thread, the current thread enters the blocking waiting schedule and finally acquires the lock. Can be blocked, can respond to thread interruption, throwing InterruptedException exception.
  • boolean tryLock():only try to get the lock once, if the lock is idle, obtain the lock and immediately return true, no matter whether there are other threads waiting to acquire the lock in the queue at this time, it is equivalent to insert queue , And this kind of skipping behavior directly ignores whether the lock is fair; if the lock is held by another thread, it immediately returns false. It cannot be blocked, and it cannot respond to interrupts.
  • boolean tryLock(long time, TimeUnit unit) throws InterruptedException:When the lock is idle, the current thread immediately acquires the lock and returns true; when the lock is held by another thread, it enters the block and waits for the schedule to be obtained before the timeout arrives The lock. If the lock can be finally obtained, it returns true, otherwise it returns false. Can be blocked(maximum blocking time is defined by timeout), and can respond to thread interruption. In its implementation class ReentrantLock, this method behaves differently when using fair locks. If the current lock is idle, but there are other threads waiting in the queue to acquire the lock, then the current thread will not "queue" but enter the queue to wait to ensure fairness.

3 . Performance comparison between explicit lock and built-in lock

In Java 5 and earlier versions, the concurrency performance of explicit locks is significantly better than the built-in locks of objects. But starting with Java 6, as the JVM continues to optimize the syncronized keyword, the concurrent performance of the two is very close. Therefore, unless the built-in lock cannot meet the design requirements of concurrent programs, it is generally recommended to use the synchonized built-in lock.

4 . Talk about the fairness of the lock

The difference between a fair lock and an unfair lock is that in an unfair lock, only when the lock is held by a certain thread will the current thread be put into the lock's waiting queue. In other words, if an unfair lock is used, if a thread sees that the lock is currently available, no matter whether other threads are already waiting for the lock in the queue, the current thread will play rogues.

Unless the fairness of the lock will affect the correctness of the program execution, in general, it is recommended to use unfair locks, because the concurrency performance of unfair locks is better. At the same time, Java does not require the JVM to implement built-in locks in a fair manner.