In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly introduces "what are the basic principles of synchronized and ReentrantLock". In daily operation, I believe that many people have doubts about the basic principles of synchronized and ReentrantLock. The editor consulted all kinds of materials and sorted out simple and easy-to-use methods of operation. I hope it will be helpful to answer the doubts about "what are the basic principles of synchronized and ReentrantLock?" Next, please follow the editor to study!
Type of java lock
There are several types of locks for java.
Optimistic lock and pessimistic lock
Optimistic locking is that JVM believes that concurrency correctness can be guaranteed without locking. Typical implementations are those such as AtomicInteger.
Pessimistic locking is the need for locking mutual exclusion. The typical implementation is Synchronized (whether Synchronized is an optimistic lock or a pessimistic lock is actually related to the specific implementation, which is pessimistic lock in most scenarios) and ReentrantLock.
Reentrant and non-reentrant
Reentrant means that when a thread acquires the lock but does not release it, and the thread acquires the lock again, it can still succeed. Both Synchronized and ReentrantLock are reentrant locks.
Non-reentrant is a reentrant negative proposition, so that you will lock yourself up. There should be no such implementation.
Fair lock and unfair lock
A fair lock is that the thread that requests the lock first must acquire the lock first, that is, FIFO. Is it fair to say it is reasonable? It may not be necessary, because this will result in a context switch. ReentrantLock is an unfair lock by default, but a fair lock instance can be constructed by constructor.
An unfair lock means that a new thread has a priority to acquire the lock, that is, it can jump the queue. Is it reasonable? It may also be unreasonable, because this can lead to "starvation": the old thread in the queue always cannot get the lock. Sysnchronized is actually an unfair lock.
Exclusive lock and shared lock
An exclusive lock is that after one thread acquires the lock, other threads can no longer acquire the lock. Exclusive locks are used in most scenes.
Shared lock means that multiple threads can acquire the lock at the same time. It is common that multiple threads can acquire read locks at the same time.
II. Synchronized
The basic principles of synchronized are implemented through CPU instructions. It was a heavy lock before jdk1.6. Because the multithread of java corresponds to the thread of the operating system one by one. When the java thread is blocked, it needs to be blocked by the thread that switches to the kernel state, and when it wakes up, it has to switch from the kernel state to the user mode, which makes a heavy context switch. So can a thread not block when it can't get the lock? Is spin okay? This gives you four implementations of synchronized: no lock, bias lock, lightweight lock, and weight lock.
Synchronized locks the object header of java, and in more detail, mark word.
No lock
There's nothing to say about this. This object is not included through synchronized.
Bias lock
When only one thread is accessing the lock, the threadId of the current thread is set in mark word by CAS. If successful, the lock is successful (since there is only one thread, it will be successful). So when this thread requests a lock again, see if the thread id of mark word is the same as itself, and if the same lock succeeds. Note that there is no unlock operation. If another thread comes, the CAS of this new thread must fail because the previous thread did not unlock the operation. At this point, when the JVM has no bytecode to execute (global safety point), it will check whether the last thread has finished, and if so, update the thread id field in the mark word to the threadId of the new thread through CAS. If the previous thread does not end, there is concurrency. The bias lock cannot complete the mission and needs to be upgraded to a lightweight lock.
Light weight lock
Then follow the example of the previous thread An and the new thread B that favor the lock above. At this point, JVM performs the operation of thread An on mark word. Copy the mark word to the stack space of the current thread, the pointer of the CAS operation mark word points to the address of the stack space, and the CAS operation the stack space of the current thread plus a pointer to mark word. After these two operations are successful, the first CAS success is a success, so thread An acquires the lock and upgrades it to a lightweight lock. Thread B spins and waits for the release of thread A. How does thread A release the lock? As long as the pointer of the first CAS operation (the pointer of the mark word to the thread stack) is released, thread B spins to detect the direction of the mark word to preempt the lock. What if there is another thread C at this time? Do you spin, too? How many threads can spin at the same time? How many times can thread B spin? These are configurable with JVM parameters.
Weight lock
There's actually nothing to say about this. When there is concurrent access, switch the thread directly to kernel state blocking.
III. ReentrantLock
ReentrantLock is implemented through AQS (AbstractQueuedSynchronizer). Problems that need to be solved:
A state is needed to indicate whether the lock object has been preempted and, if so, how many times it has been preempted by this thread. This status identifier is actually the state member variable of AQS. Operations on state must be thread-safe. It can be solved through CAS.
Protected final boolean tryAcquire (int acquires) {final Thread current = Thread.currentThread (); int c = getState (); if (c = = 0) {/ / this is the implementation of fair locking. You need to determine whether there are any waiting threads in the queue. / / if there is no CAS preemption if (! hasQueuedPredecessors () & & compareAndSetState (0, acquires)) {setExclusiveOwnerThread (current); return true }} / / here is the reentrant logic else if (current = = getExclusiveOwnerThread ()) {int nextc = c + acquires; if (nextc < 0) throw new Error ("Maximum lock count exceeded"); setState (nextc); return true;} return false;}
Multiple threads preempt lock at the same time, only one thread can succeed, how can other threads queue up? How does the queued thread seize the lock? This uses a queue. This queue is inserted through spin and CAS.
Private Node addWaiter (Node mode) {Node node = new Node (mode); / / Loop attempt for (;;) {Node oldTail = tail; if (oldTail! = null) {/ / modify the front pointer node.setPrevRelaxed (oldTail) without lock / / CAS modify tail if (compareAndSetTail (oldTail, node)) {/ / modify subsequent pointer oldTail.next = node; return node;}} else {initializeSyncQueue ();}
What about queued threads preempting lock?
Final boolean acquireQueued (final Node node, int arg) {boolean interrupted = false; try {for (;;) {final Node p = node.predecessor (); / / if the precursor node is a header node and the lock is acquired successfully, return directly. / / but in most cases, it may not be so lucky. If (p = = head & & tryAcquire (arg)) {setHead (node); p.next = null; / / help GC return interrupted } / / whether blocking if (shouldParkAfterFailedAcquire (p, node)) / / blocking interrupted here | = parkAndCheckInterrupt ();}} catch (Throwable t) {cancelAcquire (node); if (interrupted) selfInterrupt (); throw t;}}
How to wake up the blocked thread above? This depends on the release logic.
Public final boolean release (int arg) {/ / release lock if (tryRelease (arg)) {Node h = head; if (h! = null & & h.waitStatus! = 0) unparkSuccessor (h); / / wake up the subsequent nodes of the header node. Note that the head node is a virtual node, and there is no real meaning return true;} return false;}. At this point, the study on "what are the basic principles of synchronized and ReentrantLock" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.