How to correctly use wait, policy, and policyall in Java

Source: Internet
Author: User

How to correctly use wait, policy, and policyall in Java

Wait, policy, and policyall are reserved keywords that are frequently used in multithreading, but they are not valued in actual development. This article describes the use of these keywords.

In Java, you can use wait, policy, and policyall to implement inter-thread communication .. For example, if your Java program has two threads-producer and consumer, the producer can notify the consumer to start consuming data, because the content to be consumed in the queue's slow-forward zone is not empty ). Correspondingly, the consumer can notify the producer to start generating more data, because when it consumes some data, the buffer is no longer full.

We can use wait () to pause a thread under certain conditions. For example, in the producer consumer model, when the producer thread is full and the consumer is empty in the buffer zone, the operation should be suspended. If some threads are waiting for certain conditions to be triggered, you can use policy and policyall to notify the waiting threads to start running again when the conditions are true. The difference is that notify only notifies one thread, and we don't know which thread will receive the notification. However, notifyAll notifies all the waiting threads. In other words, if there is only one thread waiting for a signal lamp, Y and notifyAll will notify this thread. However, if multiple threads are waiting for this signal light, notify will only notify one of them, while other threads will not receive any notifications, and notifyAll will wake up all the waiting threads.

In this article, you will learn how to use wait, notify, and yyall to implement inter-thread communication and solve the producer and consumer problems. If you want to learn more about multithreading synchronization in Java, I strongly recommend that you read Java Concurrency in Practice | Java Concurrency practices by Brian Goetz. without reading this book, your Java multi-thread journey is incomplete! This is one of the books I recommend most to Java developers.

How to Use Wait

Although the concepts of wait and policy are very basic, they are also Object-class functions, but it is not easy to use them to write code. If you ask a candidate to write code in the interview and use wait and policy to solve producer and consumer problems, I am almost sure that most of them will be at a loss or make some mistakes, for example, if the synchronized keyword is used in the wrong place, wait is not used for the correct object, or the standard code method is not followed. To be honest, this problem is indeed a headache for programmers who do not often use them.

The first question is, how can we use wait () in code? Because wait () is not a function in the Thread class, we cannot use Thread. call (). In fact, many Java Programmers like this because they are used to using Thread. sleep (), so they will try to use wait () to achieve the same goal, but soon they will find that this cannot solve the problem smoothly. The correct method is to use wait for the Object shared among multiple threads. In the producer consumer issue, this shared Object is the Buffer Queue.

The second problem is that, since we should call wait in the synchronized function or object, which object should be synchronized? The answer is that the object you want to lock should be synchronized, that is, the object shared among multiple threads. In the producer consumer issue, synchronized should be the Buffer Queue. I think there is a problem with the original English text ...... Originally, the end of the sentence should not be a question mark, or it will not be too smooth ......)

Always call wait and Policy in loop), not in the If statement

Now you know that wait should always be called on the multi-thread shared object in the context of synchronized. The next thing you must remember is that you should always be in the while LOOP, instead of calling wait in the if statement. Because the thread is waiting under certain conditions-in our example, "If the Buffer Queue is full, the producer thread should wait ", you may intuitively write an if statement. However, the if statement has some minor issues that may cause your thread to be awakened incorrectly even if the conditions are not met. Therefore, if you use the while loop to check whether the wake-up conditions are met after the thread is awakened, your program may encounter errors. For example, when the buffer is full, the producer continues to generate data, or when the buffer is empty, the consumer starts to make small data. So remember, always use wait in the while LOOP instead of the if statement! I will recommend reading objective Java, which is the best reference for correct use of wait and policy.

Based on the above cognition, the following is a standard code template using the wait and notify functions:

 
 
  1. // The standard idiom for calling the wait method in Java 
  2. synchronized (sharedObject) { 
  3.     while (condition) { 
  4. sharedObject.wait(); 
  5.         // (Releases lock, and reacquires on wakeup) 
  6.     } 
  7.     // do action based upon condition e.g. take or put into queue 

As I said before, the purpose of using wait in the while loop is to continuously check whether the conditions are met before and after the thread is awakened. If the condition does not change, the wait will be triggered by the wake-up notification sent by notify before the call. This thread cannot be awakened and may cause a deadlock.

Java wait (), Y (), policyall () Example

The following is an example program using wait and policy. In this program, we use some code specifications described above. We have two threads named PRODUCER Producer and CONSUMER Consumer respectively. They inherit the Producer and Consumer classes respectively, while both PRODUCER and CONSUMER inherit the Thread classes. 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 queue list as a buffer queue in Java. The queue List implements the queue interface ). The producer inserts a random integer into the consumer list in an infinite loop until the consumer list is full. We check this condition in the while (queue. size = maxSize) loop statement. Note that we have used the synchronized keyword on the queue object before doing this check condition, so other threads cannot change this queue when we check the condition. If the queue is full, the PRODUCER thread will consume any integer in the CONSUMER thread's queue and notify the PRODUCER thread to wait until the queue is full. In our example, both wait and policy are used on the same shared object.

 
 
  1. import java.util.LinkedList; 
  2. import java.util.Queue; 
  3. import java.util.Random; 
  4. /** 
  5. * Simple Java program to demonstrate How to use wait, notify and notifyAll() 
  6. * method in Java by solving producer consumer problem. 
  7. * @author Javin Paul 
  8. */ 
  9. public class ProducerConsumerInJava { 
  10. public static void main(String args[]) { 
  11.   System.out.println("How to use wait and notify method in Java"); 
  12.   System.out.println("Solving Producer Consumper Problem"); 
  13.   Queue<Integer> buffer = new LinkedList<>(); 
  14.   int maxSize = 10; 
  15.   Thread producer = new Producer(buffer, maxSize, "PRODUCER"); 
  16.   Thread consumer = new Consumer(buffer, maxSize, "CONSUMER"); 
  17.   producer.start(); consumer.start(); } 
  18. /** 
  19. * Producer Thread will keep producing values for Consumer 
  20. * to consumer. It will use wait() method when Queue is full 
  21. * and use notify() method to send notification to Consumer 
  22. * Thread. 
  23. * @author WINDOWS 8 
  24. */ 
  25. class Producer extends Thread 
  26. { private Queue<Integer> queue; 
  27.   private int maxSize; 
  28.   public Producer(Queue<Integer> queue, int maxSize, String name){ 
  29.    super(name); this.queue = queue; this.maxSize = maxSize; 
  30.   } 
  31.   @Override public void run() 
  32.   { 
  33.    while (true) 
  34.     { 
  35.      synchronized (queue) { 
  36.       while (queue.size() == maxSize) { 
  37.        try { 
  38.         System.out .println("Queue is full, " + "Producer thread waiting for " + "consumer to take something from queue"); 
  39.         queue.wait(); 
  40.        } catch (Exception ex) { 
  41.         ex.printStackTrace(); } 
  42.        } 
  43.        Random random = new Random(); 
  44.        int i = random.nextInt(); 
  45.        System.out.println("Producing value : " + i); queue.add(i); queue.notifyAll(); 
  46.       } 
  47.      } 
  48.     } 
  49.    } 
  50. /** 
  51. * Consumer Thread will consumer values form shared queue. 
  52. * It will also use wait() method to wait if queue is 
  53. * empty. It will also use notify method to send 
  54. * notification to producer thread after consuming values 
  55. * from queue. 
  56. * @author WINDOWS 8 
  57. */ 
  58. class Consumer extends Thread { 
  59.   private Queue<Integer> queue; 
  60.   private int maxSize; 
  61.   public Consumer(Queue<Integer> queue, int maxSize, String name){ 
  62.    super(name); 
  63.    this.queue = queue; 
  64.    this.maxSize = maxSize; 
  65.   } 
  66.   @Override public void run() { 
  67.    while (true) { 
  68.     synchronized (queue) { 
  69.      while (queue.isEmpty()) { 
  70.       System.out.println("Queue is empty," + "Consumer thread is waiting" + " for producer thread to put something in queue"); 
  71.       try { 
  72.        queue.wait(); 
  73.       } catch (Exception ex) { 
  74.        ex.printStackTrace(); 
  75.       } 
  76.      } 
  77.      System.out.println("Consuming value : " + queue.remove()); queue.notifyAll(); 
  78.     } 
  79.    } 
  80.   } 

To better understand this program, I suggest you run it in debug mode. Once you start the program in debug mode, it will stop on the PRODUCER or CONSUMER thread, depending on which thread occupies the CPU. Because both threads have wait () conditions, they will definitely stop, then you can run the program and check what happened. It is very likely that it will output the content shown above ). You can also use the Step into and Step over buttons in Eclipse to better understand what happens between multiple threads.

Focus of this article:

1. You can use the wait and notify functions to implement inter-thread communication. You can use them to implement multi-thread> 3) communication.

2. Always use wait, policy, and policyall in synchronized functions or objects. Otherwise, the Java Virtual Machine will generate IllegalMonitorStateException.

3. Always use wait in the while LOOP instead of the if statement. In this way, the loop will check the wait conditions before and after the thread goes to sleep, and handle the wake-up notification without actually changing the conditions.

4. Always use wait on the multi-thread shared object in the producer consumer model, that is, the buffer queue.

5. For the reasons mentioned above, policyall () rather than policy () is preferred ().

This is all about how to use wait, policy, and policyall in Java. You should use these functions only when you know what you want to do. Otherwise, there are many other solutions to solve the synchronization problem in Java. For example, if you want to use the producer and consumer model, you can also use BlockingQueue, which will help you deal with all thread security issues and process control. If you want a thread to wait for feedback from another thread to continue running, you can also use CycliBarrier or CountDownLatch. If you only want to protect a certain resource, you can also use Semaphore.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.