Must-ask series | 12 pictures to show you a thorough understanding of various locks in Java~

insert image description here
Read the original text: Must-ask series | 12 pictures to show you a thorough understanding of various locks in Java ~

Preamble

Hello everyone, I am Xiaolong.

See you again~

Today I want to talk to you about various locks in Java. Fortunately, I am often asked about this in the autumn recruitment interview, so I sorted it out in detail and shared it with you. I will be able to do it with ease in the next interview~

Before reading the text, you can close your eyes and recall these questions.

Interviewer : " 对锁了解吗?谈谈你知道的锁?何为乐观锁?怎样实现?分段锁哪里有体现?这样设计有什么好处?"

If you can recall it quickly, it means that the foundation is still very solid. But don't worry, you can continue to look down, maybe there will be unexpected gains.

If you feel very vague, then this article is just right for you. The re-recording is in progress, and the spring recruitment is about to proceed. Students who did not get the ideal offer in the autumn recruit quickly collected and forwarded it.

Pessimistic lock and optimistic lock

pessimistic lock

Why pessimistic? It is always in a negative and pessimistic state, so the pessimistic lock feels that there may be problems with concurrent operations every time, so it will lock every time.

To explain in a little more detail:

悲观锁It is believed that the concurrent operation of the same data must be modified, even if there is no modification, it will be considered modified. Therefore, for concurrent operations on the same data, 悲观锁采取加锁的形式. Pessimistically think that concurrent operations without locks will definitely cause problems.

--Xiaolong's hand-painted: pessimistic lock--

As shown in the figure, assuming that there are multiple threads wanting to operate the same resource object, someone may think of using a mutex for synchronization, and its synchronization method is pessimistic. I think that if the thread calls are not strictly synchronized, there will be problems. Therefore, a mutex locks a resource for use by only one thread.

optimistic lock

何为乐观? It is always in an optimistic and positive state, so optimistic locks feel that there will be no problems during concurrent operations. The operation data is not locked . It will only check whether the data has been modified when the data is updated at the end. If not, it will be updated.

Xiaolong hand-painted: Optimistic lock

Usually optimistic locking can be implemented with CAS算法or vision版本机制. In Java, java.util.concurrent.atomicthe atomic class under the package is implemented using CAS.

Since CAS is mentioned, this is also a high-frequency interview question. Here is a brief introduction to CAS, which can be understood by linking optimistic locking and CAS.

CAS is an optimistic lock implementation mechanism, mainly composed of three parts, memory value + old expected value + value to be modified. Every time the data is modified, first compare whether the value in the memory is the same as the expected value. If it is different, it will spin, and if it is the same, it will be modified. Realization relies on unsafe(the inside is full of native modified local methods, which can directly call the operating system) + lock cmpxchg(the bottom layer relies on hardware instructions).

As shown in the figure, the original shared variable old value=0, the thread modifying the data first compares whether the value in the memory is 0, if it is 0, it means that there is no thread occupation, then it is changed to new value=1, when other threads arrive, they find that the memory If the value is different from the old value, it spins and waits.

Disadvantages of CAS:

  • May cause ABA (version)problems - when a value is updated from A to B, and then changed back, the normal CAS mechanism can't find it.
  • Always wasting resources: If the amount of concurrency is high, many threads repeatedly try to update variables but fail to update, and the cycle goes on and on, which will bring high CPU consumption.
  • The atomicity of the code block cannot be guaranteed: only the atomic operation of a variable can be guaranteed, and the code block must be sychronized.

Optimistic locking and pessimistic locking usage scenarios

These two types of locks have their own advantages and disadvantages. Only when the appropriate lock is used in the appropriate scene can the respective advantages be maximized.

Optimistic locking is suitable for scenarios with more reads and fewer writes, because it is not locked. Compared with pessimistic locking, it does not need to lock or release locks, which saves overhead. However, if there are too many writes, the conflicts will be serious, which may cause the thread to spin all the time, wasting resources and degrading performance. At this time, it is more appropriate to use pessimistic locks in this scenario of writing more and reading less.

Exclusive and shared locks

exclusive lock

独享锁Also called 排他锁, it means that the lock can only be held by one thread at a time. If thread T adds an exclusive lock to data A, other threads cannot add any type of lock to A. A thread that acquires an exclusive lock can both read and modify data. The implementation classes of synchronized in JDK and Lock in JUC are mutexes.

Xiaolong hand-painted: exclusive lock

shared lock

共享锁It means that the lock can be held by multiple threads. If thread T adds a shared lock to data A, other threads can only add shared locks to A, and cannot add exclusive locks. A thread that acquires a shared lock can only read data, but not modify it.

Xiaolong hand-painted: shared lock

It should be noted that for Java ReentrantLock, it is an exclusive lock. But for another implementation class of Lock, ReadWriteLock, its read lock is a shared lock, and its write lock is an exclusive lock.

The shared lock of the read lock can ensure that concurrent reading is very efficient, and the process of reading and writing, writing and reading, and writing and writing are mutually exclusive.

Exclusive locks and shared locks are also implemented through AQS, by implementing different methods to achieve exclusive or shared.

For synchronized, of course it is an exclusive lock.

Fair locks and unfair locks

fair lock

公平锁It means that multiple threads acquire locks in the order in which they apply for locks, and the threads directly enter the queue to queue up, and the first thread in the queue can acquire the lock.

Xiaolong hand-painted: fair lock

The advantage of a fair lock is the thread waiting for the lock 不会饿死. The disadvantage is that as a whole 吞吐效率相对非公平锁要低, all threads except the first thread in the waiting queue will be blocked, and the overhead of CPU waking up blocked threads is greater than that of unfair locks.

unfair lock

非公平锁When multiple threads are locked, they directly try to acquire the lock. If they cannot acquire it, they will wait at the end of the waiting queue. But if the lock is just available at this time, then this thread can directly acquire the lock without blocking, so unfair locks may occur where the thread that applies for the lock acquires the lock first.

The advantage of unfair locks is that it is possible 减少唤起线程的开销,整体的吞吐效率高, because threads have a chance to obtain locks directly without blocking, and the CPU does not have to wake up all threads. The disadvantage is that it is in 等待队列中的线程可能会饿死, or it will take a long time to get the lock.

Xiaolong hand-painted: unfair lock

In Java, synchronizedit is an unfair lock, ReentrantLockwhich can be an unfair lock or a fair lock, and the default is an unfair lock.

//此处创建一个非公平锁,默认就是非公平,true 表示公平,false 表示公平。
Lock lock =new ReentrantLock(flase);

Now that we have talked about synchronizedand here ReentrantLock, let's make a simple comparison with Lock by the way.

  • Source: synchronized is a keyword, lock is an interface, and the implementation class performs lock operations.
  • Whether you know to acquire a lock: synchronized cannot judge the state of the lock, but lock can judge whether to acquire the lock (boolean b =lock.tryLock();)
  • Whether to release the lock: synchronized automatically releases the lock, lock is manually released (easy to deadlock) lock.unlock(); after synchronized is blocked, other threads wait all the time, and the lock has a timeout.
  • synchronized reentrant lock (acquiring the same lock multiple times), non-interruptible, unfair lock; lock, the default is unfair lock, can be set to fair.
  • Scheduling mechanism: synchronized uses the wait, notify, and notifyAll scheduling mechanisms of the Object object itself, while Lock can use Condition to schedule between threads.
  • Whether to respond to interrupts: lock can use interrupt to interrupt the wait while waiting for the lock, while synchronized can only wait for the release of the lock and cannot respond to interrupts.

segment lock

分段锁In fact, it is a lock design, not a specific lock, which is reflected in the ConcurrentHashMap JDK1.7 version. Its concurrent implementation is realized in the form of segment locks 高效的并发操作.

Xiaolong hand-painted: segment lock

What is segment lock? Why introduce segment locks?

Let's compare it with Hashtable. We all know that Hashtable is concurrently safe, but its efficiency is very low because it locks the entire table. This greatly reduces performance. The ConcurrentHashMap JDK1.7 introduced segment locks.

A segment is equivalent to a lock, it only locks this slot, and the others are not affected. ConcurrentHashMap divides the hash table into 16 buckets (the default value), and common operations such as get, put, and remove only lock the buckets currently needed.

Imagine that only one thread can enter in the past, but now 16 writing threads can enter at the same time (only the writing thread needs to be locked, and the reading thread is almost unlimited, which will be mentioned later). The improvement of concurrency is obvious.

The data structure in ConcurrentHashMap JDK1.7 is composed of Segment array + HashEntry array + linked list.

Segment inherits ReentrantLock, and a Segment[i] is a segment lock. Compared with Hashtable, the lock granularity is finer and the performance is higher.

一个Segment中包含一个HashEntry数组,每个HashEntry又是一个链表结构

static final class Segment<K,V> extens ReentrantLock implements Serializable{
    
    

transient volatile HashEntry<K,V>[] tables;
//.....
}
static final class HashEntry<K,V>
{
    
    
  final int hash;
  final K key;
  volatile V value;
  volatile HashEntry<K,V> next;
}

reentrant lock

可重入锁Also known as 递归锁, it means that when the same thread acquires the lock in the outer method, it will automatically acquire the lock when entering the inner method.

synchronized void getA() throws Exception{
    
    
  Thread.sleep(1000);
  getB();
}

synchronized void getB() throws Exception{
    
    
  Thread.sleep(1000);
}

Xiaolong hand-painted: reentrant lock

For Java ReetrantLock, it can be seen from the name that it is a reentrant lock, and its name is Reentrant Lock reentrant lock. For Synchronized, it is also a reentrant lock. One advantage of reentrant locks is that deadlocks can be avoided to a certain extent.

Here is my analysis of the AQS of the JDK source code drawing 源码解析流程图, which can give you a good understanding of the internal 非公平锁and 可重入锁specific implementation. It may be a bit vague here, if necessary, you can reply to [AQS] in the background to collect it.

AQS principle analysis

spin lock

自旋锁It means that the thread will not block immediately when the lock is not acquired, and will keep looping while trying to acquire the lock. This is called spin.

Dragon hand drawing: spin lock

Spinning can reduce thread suspension, thereby reducing the consumption of thread context switching.

However, if the lock is occupied by a thread for a long time, it will waste system resources and reduce the overall performance instead.

Xiaolong has something to say

This article introduces all kinds of locks in Java in a graphical way. I also like to test this part of the interview. I hope you can come down and have a look at this related knowledge~

If you like this graphic series of articles, please leave a message and pay attention . Xiaolong is committed to sharing knowledge with you in the most easy-to-understand way~

I'm Xiaolong, see you next time.

--------------End of article--------------

Ask for one-click triple link : I hope to forward , watch , and share with more students~

Public account : Dachang advanced guide, focusing on sharing back-end technology, school recruitment interviews and job hunting~

Meeting must be fate, I hope everyone will give a little attention ! Your support is my great motivation, more high-quality and good articles are waiting for you to explore, love you~

Fan benefits : Reply in the backstage [Help Gift Pack] to receive a full set of strategies for school recruitment and job hunting; reply to [Smart Campus Assistant based on artificial intelligence] to receive boutique projects for school recruitment and job hunting.

Guess you like

Origin blog.csdn.net/qq_43666365/article/details/121771423