In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article will explain in detail how to correctly use wait, notify and notifyAll in Java. The editor thinks it is very practical, so I share it with you as a reference. I hope you can get something after reading this article.
Wait, notify and notifyAll, which are often used in multithreading, are often ignored in actual development. This article describes the use of these keywords.
In Java, wait, notify and notifyAll can be used to realize the communication between threads. For example, if you have two threads in your Java program, the producer and the consumer, the producer can notify the consumer to start consuming data because there is content in the queue buffer for consumption (not empty). Accordingly, consumers can inform producers that they can start generating more data because the buffer is no longer full when it consumes some data.
We can use wait () to suspend a thread under certain conditions. For example, in the producer-consumer model, the producer thread should pause when the buffer is full and the consumer should pause when the buffer is empty. If some threads are waiting for certain conditions to be triggered, you can use notify and notifyAll to tell those waiting threads to start running again when those conditions are true. The difference is that notify notifies only one thread, and we don't know which thread will receive the notification, whereas notifyAll notifies all waiting threads. In other words, if only one thread is waiting for a semaphore, both notify and notifyAll will notify that thread. But if multiple threads are waiting for the signal light, notify will notify only one of them, while the other threads will not receive any notification, and notifyAll will wake up all waiting threads.
How to use Wait
Although the concepts of wait and notify are basic, and they are functions of the Object class, it is not easy to write code with them. If you ask candidates to handwrite code in an interview and use wait and notify to solve producer-consumer problems, I'm almost sure that most of them will be at a loss or make some mistakes, such as using the synchronized keyword in the wrong place, not using wait for the right object, or not following the standard code method. To be honest, this problem is really a headache for programmers who don't use them very often.
The question is, how do we use wait () in our code? Because wait () is not a function under the Thread class, we cannot use Thread.call (). In fact, many Java programmers like to write this, because they are used to using Thread.sleep (), so they will try to use wait () to achieve the same goal, but they will soon find that this does not solve the problem smoothly. The right way to do this is to use wait for the Object that is shared among multiple threads. In the case of producer-consumer problems, the shared Object is the buffer queue.
The second question is, since we should call wait in a function or object in synchronized, which object should be synchronized? The answer is that the object you want to lock should be synchronized, that is, the object that is shared among multiple threads. In the case of producers and consumers, it is the buffer queue that should be synchronized. I think there is something wrong with the original English text. It shouldn't be a question mark at the end of that sentence, otherwise it doesn't make much sense. )
Always call wait and notify in the loop, not in the If statement
Now that you know that wait should always be called in the context of being synchronized and on the object that is shared by multithreading, the next thing to remember is that you should always call wait in the while loop, not in the if statement. Because threads wait under certain conditions-in our case, "if the buffer queue is full, then the producer thread should wait", you might intuitively write an if statement. However, there are some subtle problems with the if statement, so that even if the conditions are not met, you may be incorrectly awakened by your thread. So if you don't use the while loop again after the thread is woken up to check that the wake-up condition is met, your program may go wrong-for example, the producer continues to generate data when the buffer is full, or consumers start small data when the buffer is empty. So remember, always use wait in while loops instead of if statements! I would recommend reading "Effective Java", which is a reference on how to use wait and notify correctly.
Based on the above knowledge, the following is a canonical code template that uses the wait and notify functions:
/ / The standard idiom for calling the wait method in Java synchronized (sharedObject) {while (condition) {sharedObject.wait (); / / (Releases lock, and reacquires on wakeup)} / / do action based upon condition e.g. Take or put into queue}
As I said before, the purpose of using wait in a while loop is to continuously check that the condition is met before and after the thread is awakened. If the condition does not change, the wake-up notification of the wait comes before the notify is called, then the thread is not guaranteed to be woken up, which may lead to deadlock problems.
Examples of Java wait (), notify (), notifyAll ()
Here we provide a sample program that uses wait and notify. In this program, we use some of the code specifications described above. We have two threads named PRODUCER (producer) and CONSUMER (consumer), which inherit the Producer and Consumer classes, respectively, while Producer and Consumer both inherit the Thread class. The code logic that Producer and Consumer want to implement is in the run () function. The Main thread starts the producer and consumer threads and declares a LinkedList as a buffer queue (in Java, LinkedList implements the interface to the queue). The producer continues to insert random integers into the LinkedList in the * loop until the LinkedList is full. We check this condition in the while (queue.size = = maxSize) loop statement. Notice that we used the synchronized keyword on the queue object before doing this check condition, so other threads cannot change the queue when we check the condition. If the queue is full, the PRODUCER thread waits until the CONSUMER thread consumes any integer in the queue and notifies the PRODUCER thread with notify. In our example, wait and notify are both used on the same shared object.
Import java.util.LinkedList; import java.util.Queue; import java.util.Random; / * * Simple Java program to demonstrate How to use wait, notify and notifyAll () * method in Java by solving producer consumer problem. * * @ author Javin Paul * / public class ProducerConsumerInJava {public static void main (String args []) {System.out.println ("How to use wait and notify method in Java"); System.out.println ("Solving Producer Consumper Problem"); Queue buffer = new LinkedList (); int maxSize = 10; Thread producer = new Producer (buffer, maxSize, "PRODUCER"); Thread consumer = new Consumer (buffer, maxSize, "CONSUMER"); producer.start (); consumer.start () }} / * Producer Thread will keep producing values for Consumer * to consumer. It will use wait () method when Queue is full * and use notify () method to send notification to Consumer * Thread. * * @ author WINDOWS 8 * * / class Producer extends Thread {private Queue queue; private int maxSize; public Producer (Queue queue, int maxSize, String name) {super (name); this.queue = queue; this.maxSize = maxSize } @ Override public void run () {while (true) {synchronized (queue) {while (queue.size () = = maxSize) {try {println ("Queue is full," + "Producer thread waiting for" + "consumer to take something from queue"); queue.wait ();} catch (Exception ex) {ex.printStackTrace () } Random random = new Random (); int I = random.nextInt (); System.out.println ("Producing value:" + I); queue.add (I); queue.notifyAll ();}} / * Consumer Thread will consumer values form shared queue. * It will also use wait () method to wait if queue is * empty. It will also use notify method to send * notification to producer thread after consuming values * from queue. * * @ author WINDOWS 8 * * / class Consumer extends Thread {private Queue queue; private int maxSize; public Consumer (Queue queue, int maxSize, String name) {super (name); this.queue = queue; this.maxSize = maxSize } @ Override public void run () {while (true) {synchronized (queue) {while (queue.isEmpty ()) {System.out.println ("Queue is empty," + "Consumer thread is waiting" + "for producer thread to put something in queue"); try {queue.wait ();} catch (Exception ex) {ex.printStackTrace () System.out.println ("Consuming value:" + queue.remove ()); queue.notifyAll ();}
To better understand this program, I suggest you run it in debug mode. Once you start the program in debug mode, it stops on the PRODUCER or CONSUMER thread, depending on which thread occupies the CPU. Because both threads have wait () conditions, they must stop, and then you can run the program and see what happens (most likely it will output what we have shown above). You can also use the Step into and Step over buttons in Eclipse to better understand what's going on in multithreading.
The focus of this article is as follows:
1. You can use the wait and notify functions to communicate between threads. You can use them to communicate between multiple threads (> 3).
two。 Always use wait, notify, and notifyAll in synchronized functions or objects, otherwise the Java virtual machine generates IllegalMonitorStateException.
3. Always use wait in the while loop rather than under the if statement. In this way, the loop checks the condition of the wait before and after the thread sleeps and processes the wake-up notification if the condition has not actually changed.
4. Always use wait on objects shared between multiple threads (in the producer-consumer model, that is, buffer queues).
5. For the reasons mentioned earlier, you prefer to use notifyAll () rather than notify ().
This is all the emphasis on how to use wait, notify and notifyAll in Java. You should use these functions only if you know what you are going to do, otherwise there are many other solutions in Java to solve synchronization problems. For example, if you want to use the producer-consumer model, you can also use BlockingQueue, which will help you deal with all thread safety issues and process control. If you want a thread to wait for feedback from another thread before continuing, you can also use CycliBarrier or CountDownLatch. If you just want to protect a certain resource, you can also use Semaphore.
This is the end of the article on "how to correctly use wait, notify and notifyAll in Java". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.
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.