Java Wait (), notify () and Notifyall () usage tips

Source: Internet
Author: User

This article is for Java's Wait (), notify (), Notifyall () for a detailed analysis of the introduction, the need for a friend reference.

Wait (), notify (), and Notifyall () are all methods of Java.lang.Object:
Wait (): Causes the current thread to wait until another thread invokes the Notify () method or the Notifyall () method for T His object.
Notify (): Wakes up a single thread, that's waiting on this object ' s monitor.
Notifyall (): Wakes up all threads is waiting on this object ' s monitor.

These three methods are the underlying mechanism provided by the Java language to implement inter-thread blocking (Blocking) and control in-process scheduling (inter-process communication). Before explaining how to use it, let's say two points:

1. Just as any object in Java can be a lock (lock), any object can also become a conditional queue (Condition queue). The Wait (), notify (), and Notifyall () in this object are the intrinsic (intrinsic) methods of this conditional queue.

2. An intrinsic lock of an object and its inherent conditional queue are related, in order to invoke the method of the conditional queue within object X, you must obtain the lock of Object X. This is because the mechanism of waiting for state conditions and the mechanism of guaranteeing state continuity are tightly combined.

(An object's intrinsic lock and its intrinsic condition queue is Related:in order to call any of the condition queue met Hods on object x, you must hold the lock on X. This was because the mechanism for waiting for state-based conditions are necessarily tightly bound to the mechanism fo pres Erving State consistency)

According to the above two points, when you call Wait (), notify () or Notifyall (), you must first obtain the lock, and the state variable should be protected by the lock, and the intrinsic lock object and the intrinsic condition queue object is the same object. That is, to execute wait,notify on an object, you must first lock the object, and the corresponding state variable is protected by that object lock.

After knowing how to use it, let's ask the following questions:

1. What happens when you do wait, notify, and do not get a lock?

Please look at the code:

public static void Main (string[] args) throws Interruptedexception {        object obj = new Object ();        Obj.wait ();        Obj.notifyall ();}

Executing the above code throws a Java.lang.IllegalMonitorStateException exception.

2. What happens when you execute wait, notify, without obtaining a lock on the object?

Please look at the code:

public static void Main (string[] args) throws Interruptedexception {        object obj = new Object ();        Object lock = new Object ();        Synchronized (lock) {            obj.wait ();            Obj.notifyall ();        }    }

Executing the code will also throw a java.lang.IllegalMonitorStateException exception.

3. Why do I have to get a lock on this object when I execute wait, notify?

This is because, if there is no lock, wait and notify may produce a race condition (Race Condition). Consider the following scenarios for producers and consumers:

1.1 Producer inspection conditions (e.g. full cache) 1.2 producers must wait for

2.1 Consumers consume a unit of cache---2.2 reset conditions (such as cache not full)--2.3 Call Notifyall () Wake producer

The order we want is: 1.1->1.2->2.1->2.2->2.3

In the case of multithreading, however, the order is likely to be 1.1->2.1->2.2->2.3->1.2. In other words, before the producers wait, the consumer is notifyall, so that the producers will keep waiting.

Therefore, to solve this problem, you must obtain the lock of the object during wait and notifyall to ensure synchronization.

Consider the following simple model of caching for a producer, a consumer, and a unit implemented using wait,notify:

public class Queuebuffer {int n;    Boolean valueSet = false;            synchronized int get () {if (!valueset) try {wait ();            } catch (Interruptedexception e) {System.out.println ("interruptedexception caught");        } System.out.println ("Got:" + N);        ValueSet = false;        Notify ();    return n;            } synchronized void put (int n) {if (ValueSet) try {wait ();            } catch (Interruptedexception e) {System.out.println ("interruptedexception caught");        } THIS.N = n;        ValueSet = true;        System.out.println ("Put:" + N);    Notify (); }}
public class Producer implements Runnable {    private queuebuffer q;    Producer (Queuebuffer q) {        this.q = q;        New Thread (This, "Producer"). Start ();    }    public void Run () {        int i = 0;        while (true) {            q.put (i++);}}    }
public class Consumer implements Runnable {    private queuebuffer q;    Consumer (Queuebuffer q) {        this.q = q;        New Thread (This, "Consumer"). Start ();    }    public void Run () {        while (true) {            q.get ()}        }    }
public class Main {public    static void Main (string[] args) {        Queuebuffer q = new Queuebuffer ();         New Producer (q);         New Consumer (q);         System.out.println ("Press Control-c to stop.");}     }

Therefore, the JVM illegalmonitorstateexception the hidden race Condition by throwing an exception at execution time to ensure that the object is locked for wait, notify.

Finally, take a look at a topic: Write a multithreaded program, alternating output 1,2,1,2,1,2 ...

Using Wait, notify solves:

public class Outputthread implements Runnable {    private int num;    Private Object lock;    public outputthread (int num, Object lock) {        super ();        This.num = num;        This.lock = lock;    }    public void Run () {        try {while            (true) {                synchronized (lock) {                    lock.notifyall ();                    Lock.wait ();                    SYSTEM.OUT.PRINTLN (num);}}}        catch (Interruptedexception e) {            //TODO auto-generated catch block            e.printstacktrace ();        }    }    public static void Main (string[] args) {        Final object lock = new Object ();        Thread thread1 = new Thread (new Outputthread (1,lock));        Thread thread2 = new Thread (new Outputthread (2, lock));        Thread1.start ();        Thread2.start ();    }}

Java Wait (), notify () and Notifyall () usage tips

Related Article

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.