In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-11 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly explains "what is the reason why you still need Lock with Synchronized". The content of the explanation in the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "what is the reason why you need Lock with Synchronized"?
In the field of concurrent programming, there are two core issues: mutual exclusion and synchronization.
Mutex: means that only one thread is allowed to access a shared resource at a time.
Synchronization: refers to communication and collaboration between threads.
Both of these problems can be solved with monitor (an important concept in the operating system).
The Java keyword Synchronized is already an implementation of the pipe process, so why does the Java SDK concurrent package need a Lock to implement the pipe process? Isn't that a repetition?
Let's first take a look at the four necessary conditions for deadlocks:
1. Mutual exclusion: only one thread is allowed to occupy a shared resource at a time.
2. Possess and wait: if a thread occupies one or more resources, and there are resources that are not satisfied, the existing resources will not be released.
3. Non-preemptive: other threads cannot preempt resources that have been occupied by other threads.
4. Circular waiting: thread A waits for the resources of thread B, and thread B waits for the resources of thread A. this is circular waiting.
As long as these four conditions are met, deadlocks will occur, that is to say, as long as we break one of these four conditions, deadlocks will not occur. However, Synchronized cannot break the non-preemption condition, because when Synchronized applies for resources, if the application is not available, the thread will directly enter the blocking state, and nothing can be done if it enters the blocking state, so it cannot release the resources already occupied.
So I got a Lock. Lock has three ways to break non-preemptive conditions.
1. Void lockInterruptibly () throws InterruptedException; this is an API that supports interrupts. There is no way to wake up Synchronized after it enters blocking, so to solve this problem, a method is proposed to support response to interrupts, so that threads can respond to interrupt signals when they are blocked (waiting state under lock), so that they have the opportunity to release occupied resources to break non-preemptive conditions.
2. Boolean tryLock (); this means that when you acquire the lock, you return directly if you can't get it, so you also have the opportunity to release the occupied resources to break the non-preemptive condition.
3. Boolean tryLock (long time, TimeUnit unit) throws InterrptedException; this is an API that supports timeout, that is, threads that do not have access to resources within a period of time directly return an error and do not enter the blocking state, and there is also an opportunity to release occupied resources to break non-preemptive conditions.
Then let's talk about the three implementation classes of Lock, one is ReentrantLock, and the other two are the static inner classes ReadLock and WriteLock in the ReentrantReadWriteLock class. The way to achieve it is more or less the same.
Let me briefly talk about ReentrantLock, which uses volatile's Happens-Before rules to ensure visibility. ReentrantLock holds a volatile member variable state, which reads and writes the value of state every time it acquires the lock and reads and writes the value of state every time it is unlocked. Take a look at the reduced signal code.
Volatile int state
Lock () {
State = 1
}
Unlock () {
State = 0
}
Volatile variable rule: write operation to volatile variable Happens-Before followed by read operation to this variable.
Let's look at an example:
Private final Lock lock = new ReentrantLock ()
Int a
Public void addOne () {
Lock.lock ()
Try {
A = getA () + 1
} finally {
Lock.unlock ()
}
}
Public int getA () {
Lock.lock ()
Try {
Return a
} finally {
Lock.unlock ()
}
}
Suppose there are now two threads An and B
1. According to the rules of program order: thread A, a = getA () + 1th HappensML before lock.unlock ()
2. According to the volatile variable rules: look at the lock method, state=1, which first reads the value of state, while unlock executes state=0 and writes to state. So thread A performs the unlock operation, so according to the volatile variable rule, it is the lock operation of Happens-Before thread B.
3. According to the transitivity rule: so a = getA () + 1 in thread An is the lock operation of Happens house before thread B. So after adding one to thread A, the result is visible to thread B.
Thank you for your reading, the above is the content of "what is the reason why you still need Lock with Synchronized?" after the study of this article, I believe you have a deeper understanding of what is the reason why you still need Lock with Synchronized, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
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.