18. What are the locks in multithreading?

Classification of locks

According to the classification standard, we divide the lock into the following seven categories, namely:

  • Bias lock/lightweight lock/heavyweight lock;

  • Reentrant lock/non-reentrant lock;

  • shared lock/exclusive lock;

  • Fair lock/unfair lock;

  • Pessimistic lock/optimistic lock;

  • Spin lock/non-spin lock;

  • Interruptible lock/uninterruptible lock.

The above are basically some locks that we often encounter.

1. Biased lock/lightweight lock/heavyweight lock

The first classification is biased lock/lightweight lock/heavyweight lock. These three locks specifically refer to the state of the synchronized lock, and the state of the lock is indicated by the mark word in the object header.

Bias lock

If there is no competition for this lock from the beginning to the end, then there is actually no need to lock it, just mark it. This is the idea of ​​​​biasing the lock.

After an object is initialized, when there is no thread to acquire its lock, then it is biasable. When the first thread accesses it and tries to acquire the lock, it will record this thread. If If the thread trying to acquire the lock is the owner of the biased lock, it can directly acquire the lock with very little overhead and the best performance.

lightweight lock

JVM developers find that in many cases, the code in synchronized is executed alternately by multiple threads, rather than at the same time, that is to say, there is no actual competition, or there is only short-term lock competition. Using CAS will It can be solved. In this case, it is unnecessary to use a completely exclusive heavyweight lock.

Lightweight lock means that when the lock is originally a biased lock, it is accessed by another thread, indicating that there is competition, then the biased lock will be upgraded to a lightweight lock, and the thread will try to acquire the lock by spinning instead of will get stuck.

heavyweight lock

Heavyweight locks are mutexes, which are implemented using the synchronization mechanism of the operating system, so the overhead is relatively high.

When multiple threads directly have actual competition and the lock competition time is long, the lightweight lock cannot meet the demand, and the lock will expand into a heavyweight lock.

Heavyweight locks will cause other threads that apply but cannot get the lock to enter a blocked state.

You can find the path of lock upgrade: no lock→biased lock→lightweight lock→heavyweight lock.

The lock upgrade process is automatically completed by the JVM, and developers do not need to manually intervene. Reasonable use of locks in actual development can avoid unnecessary upgrade processes, thereby improving application performance and scalability.

  • Biased locks have the best performance and can avoid performing CAS operations.
  • The lightweight lock uses spin and CAS to avoid thread blocking and wake-up caused by heavyweight locks, and its performance is moderate.
  • Heavyweight locks will block threads that cannot acquire locks, and the performance is the worst.

2. Reentrant lock/non-reentrant lock

A reentrant lock means that the thread currently holds the lock and can acquire the lock again without releasing the lock.

In the same way, a non-reentrant lock means that although the thread currently holds the lock, if you want to acquire the lock again, you must first release the lock before trying to acquire it again.

For reentrant locks, the most typical one is ReentrantLock . Just like its name, reentrant means reentrant, and it is also the most important implementation class of the Lock interface.

3. Shared lock/exclusive lock

  • Shared lock refers to our same lock can be acquired by multiple threads at the same time,
  • An exclusive lock means that the lock can only be acquired by one thread at the same time.

Our read-write lock best interprets the concepts of shared locks and exclusive locks.

  • The read lock in the read-write lock is a shared lock.
  • The write lock is an exclusive lock.

Read locks can be read at the same time and can be held by multiple threads at the same time, while write locks can only be held by one thread at most at the same time.

4. Fair lock/unfair lock

The fair meaning of fair locks is that if the thread cannot get the lock now, then the threads will all enter the waiting queue and start queuing. The thread that has waited for a long time in the waiting queue will get the lock first. mean.

The non-fair lock is not so "perfect". Under certain circumstances, it will ignore the threads that are already in the queue, and the phenomenon of queue jumping will occur.

5. Pessimistic lock/optimistic lock

The concept of pessimistic locking is that before acquiring a resource, the lock must be obtained first, so as to achieve the "exclusive" state. When the current thread is operating the resource, other threads cannot obtain the lock, so other threads cannot affect me.

Optimistic locking is just the opposite. It does not require locks to be obtained before acquiring resources, nor will resources be locked. On the contrary, optimistic locking uses the CAS concept to modify resources without monopolizing resources.

6. Spin lock/non-spin lock

The concept of the spin lock is that if the thread cannot get the lock now, it does not directly block or release CPU resources, but starts to use the loop to keep trying to acquire the lock. This loop process is vividly compared to "spin". It's like the thread is "spinning itself".

On the contrary, the concept of non-spin lock is that there is no spin process. If you can't get the lock, you will give up directly, or perform other processing logic, such as queuing and blocking.

7. Interruptible lock/uninterruptible lock

In Java, the lock modified by the synchronized keyword represents an uninterruptible lock. Once a thread applies for a lock, there is no turning back. It can only perform other logical processing after obtaining the lock.

And our ReentrantLock is a typical interruptible lock. For example, in the process of acquiring the lock using the lockInterruptibly method, if you suddenly don’t want to acquire it, you can do other things after the interruption. You don’t need to wait until the lock is acquired. leave.

Guess you like

Origin blog.csdn.net/daohangtaiqian/article/details/130624640