In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article introduces the relevant knowledge of "how to use the wait/notify/notifyAll method of java correctly". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
One: why must wait be used in synchronized-protected synchronization code?
The wait method is introduced in the source code as follows:
/ * * As in the one argument version, interrupts and spurious wakeups are * possible, and this method should always be used in a loop: * * synchronized (obj) {* while () * obj.wait () *... / / Perform action appropriate to condition *} * * This method should only be called by a thread that is the owner * of this object's monitor. See the {@ code notify} method for a * description of the ways in which a thread can become the owner of * a monitor. * / public final void wait () throws InterruptedException {wait (0);}
This means that when using the wait method, the wait method must be written in a synchronized-protected block of while code, and always determine whether the execution condition is met, continue execution if it is met, execute the wait method if not, and hold the monitor lock of the object, which is commonly known as the synchronized lock, before executing the wait method.
1.1 what are the problems caused by failure to do so? Class BlockingQueue {Queue buffer = new LinkedList (); public void give (String data) {buffer.add (data); notify ();} public String take () throws InterruptedException {while (buffer.isEmpty ()) {wait ();} return buffer.remove ();}}
You can see in the code that there are two methods, the give method is responsible for adding data to the buffer, and after it is added, the notify method is executed to wake up the waiting thread, while the take method is responsible for checking whether the entire buffer is empty, entering the wait if it is empty, and taking out a data if not empty, which is the typical producer and consumer's idea.
What exception might occur if the wait () method is not used correctly in the code shown above?
First, the consumer thread calls the take method and determines whether the buffer.isEmpty method returns true. If true means that the buffer is empty, the thread wants to wait, but before the thread calls the wait method (after while (buffer.isEmpty (), it is paused by the scheduler, so there is no time to execute the wait method.
At this point the producer starts running and executes the entire give method, which adds data to the buffer and executes the notify method, but notify has no effect because the consumer thread's wait method doesn't have time to execute, so no thread is waiting to be woken up.
At this point, the consumer thread that has just been paused by the scheduler comes back to execute the wait method and enters the wait, and the consumer may be caught in an endless wait because it misses the wake-up call of the notify in the give method.
Ps: the scheduler mentioned above pauses threads because in multithreading, the scheduling of CPU is allocated on a time slice basis, and each thread can get a certain amount of time slice. But if the thread runs out of time slices, it will be suspended and CPU resources will be released to other threads. The "judge-execute" in the code is not an atomic operation, it may be interrupted in the middle, and it is not thread-safe, so it is possible that the thread is paused before the thread calls the wait method.
1.2 the correct use of the wait () method class BlockingQueue {Queue buffer = new LinkedList (); public void give (String data) {synchronized (this) {buffer.add (data); notify () } public String take () throws InterruptedException {synchronized (this) {while (buffer.isEmpty ()) {wait ();} return buffer.remove ();}
This ensures that the notify method will never be called between the buffer.isEmpty and wait methods, improving the security of the program. In addition, the wait method releases the monitor lock, which also requires that we first enter the synchronized to hold the lock.
1.2.1 false wake-up problems can be avoided by using while structure judgment
Threads may be woken up without being notify/notifyAll, interrupted, or timed out, something we don't want to see. However, in the actual production, the probability of false awakening is very small, but the program still needs to ensure the correctness of false awakening, so it is necessary to adopt the structure of while cycle.
While (condition does not hold) obj.wait ()
In this way, even if you are falsely awakened, you will check the conditions in while again, and if you do not meet the conditions, you will continue to wait, which eliminates the risk of false awakening.
2. Similarities and differences between wait and sleep methods.
They can all block threads.
They can all respond to interrupt interrupts: if they receive an interrupt signal while waiting, they can all respond and throw an InterruptedException exception.
2.2 differences
The wait method must be used in synchronized-protected code, and the sleep method does not require this.
When the sleep method is executed in synchronous code, the monitor lock is not released, but the monitor lock is actively released when the wait method is executed.
The sleep method requires that a time must be defined, and when the time expires, it will recover actively, while for the wait method with no parameters, it means waiting forever until it is interrupted or awakened, and it will not recover actively.
Wait/notify/notifyAll is defined in the Object class, while sleep is defined in the Thread class.
2.2.1 Why is wait/notify/notifyAll defined in the Object class and sleep defined in the Thread class?
First of all, because every object in Java has a lock called monitor monitor, each object can be locked, and there is a location in the object header to hold the lock information. The locks are object-level, not thread-level, and wait/notify/notifyAll are lock-level operations, and their locks belong to objects, so it is most appropriate to define them in the Object class, because the Object class is the parent class of all objects.
Second, a thread may hold multiple locks in order to implement complex logic to cooperate with each other, and since we are asking the current thread to wait for an object's lock, it should be done by manipulating the object, not the thread.
This is the end of the content of "how to use the wait/notify/notifyAll method of java correctly". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
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.