Java Basics--java Sleep (), wait (), and notify () __java in multiple threads

Source: Internet
Author: User
Tags instance method object object thread class

One, sleep ()


Sleep () method source code:

   /** 
    * Causes the currently executing thread to sleep (temporarily cease 
    * execution) for the specified number of M Illiseconds, subject to 
    * The precision and accuracy of system timers and schedulers. The thread 
    * does not lose ownership to any monitors. 
    * * @param Millis * The length of the ' time ' in         milliseconds 
    * * 
    @throws  IllegalArgumentException 
    *          If the value of {@code Millis} is negative 
    * 
    * @throws  Interruptedexception 
    *          If any thread has interrupted the current thread. The 
    *          <i>interrupted status</i> of the current thread are 
    *          cleared when this exception is thrown. 
    */  
   

The sleep () method comes from the thread class, and the sleep () method can do the following in terms of the source explanation:

(1) sleep () to make the current thread into a stagnant state (blocking the current thread), let out the use of the cup, the purpose is not to allow the current thread alone to occupy the process of the CPU resources, to leave some time to other threads to execute the opportunity;

(2) Sleep () is a static (static) method of the thread class; Therefore, he cannot alter the object's machine lock, so when the sleeping () method is called in a synchronized block, the thread is dormant, but the object's machine lock and the wood are freed, Other threads do not have access to this object (even if sleeping holds object locks).

(3) After the sleep () hibernation time expires, the thread does not necessarily execute immediately, because other threads may be running and are not scheduled to abort execution unless the thread has a higher priority.

Code Demo:

public class Main {public  
    static void Main (string[] args) {  
        main main = new main ();  
        Main.startthread ();  
    }  
  
    /** 
     * Start thread */public  
    void Startthread () {  
        thread t = new Thread (new Runnable () {  
            @Override  
            public void Run () {  
                System.out.println () begins executing thread ... ");  
                System.out.println ("Go to sleep ...) ");  
                try {  
                    Thread.Sleep (3000);  
                } catch (Interruptedexception e) {  
                    e.printstacktrace ();  
                }  
                SYSTEM.OUT.PRINTLN ("Thread end ...") ");  
            }  
        });  
        T.start ();  
    }  
  
Run Result:
Start execution thread ...
go to sleep state ...
Thread End ...
From the results of the operation, we can see that the program, although it was interrupted 3 seconds during the run, will continue executing the code after 3 seconds, until the end of the run. During sleep, the thread holds the monitor object all the time.


second, wait ()


Wait () method source code:

    /** * Causes the current thread to wait until another thread invokes the * {@link java.lang.object#notify ( 
     ) method or the * {@link Java.lang.object#notifyall ()} method is for this Object. 
     * In other words, this is behaves exactly as if it simply * performs the call {@code wait (0)}. * <p> * The current thread must own this object monitor. The thread * Releases ownership of this monitor and waits until another thread * notifies threads waiting on t His object's monitor to wake up * either through a call to the {@code Notify} method or the * {@code notifyall } method. 
     The thread then waits until it can * re-obtain ownership of the monitor and resumes execution. * <p> * As in the one argument version, interrupts and spurious wakeups are * possible Should always is used in a loop: * <pre> * synchronized (obj) {* while (<condition does not hold>) * obj.wait (); *..///Perform action appropriate to condition *} * </pre> * This method should onl Y to called by a thread, that's the owner * of this object ' s monitor. The {@code Notify} method for A * Description of the ways in which a thread can become the owner of * a mo 
     Nitor. * * @exception illegalmonitorstateexception If the current thread was not * owner of the OB 
     Ject ' s monitor. * @exception interruptedexception If any thread interrupted the * current thread before or while the CU  Rrent thread * is waiting for a notification. The <i>interrupted * status</i> of the current thread are cleared when * th 
     Is exception is thrown. * @see java.lang.object#notify () * @see Java.lang.object#notifyall ()/public final void WaIt () throws interruptedexception {wait (0);  }

First Wait () is a method of the object class, from the interpretation of the source, the wait () method can do the following points:

(1) The Wait () method is a method in the object class, and when a thread executes to the waiting () method, it enters into an object-dependent standby pool while losing (releasing) the object's machine lock (temporarily losing the machine lock, wait (long timeout) After the timeout time, the object lock needs to be returned, and other threads can access it;

(2) Each thread must hold the monitor for that object. If the wait () method is invoked in the current thread, the thread releases the hold object of monitor and keeps itself in a waiting state.

(3) If you want to wake up a waiting thread, you need to open a thread through the Notify () or Notifyall () method to notify the waiting thread to get the monitor object. That way, the thread can break the waiting state and continue executing the code.

(4) Wiat () must be placed in synchronized block, otherwise the "java.lang.IllegalMonitorStateException" exception will be thrown when the program runtime.

Code Demo:

public class main {public static void main (string[] args) {main main = new main ();  
    Main.startthread ();  
  
    /** * Thread lock/private Final object = new Object ();  
            /** * Start thread */public void Startthread () {Thread t = new Thread (new Runnable () { @Override public void Run () {System.out.println start execution thread ...  
                "); System.out.println ("Enter the waiting State ...")  
                ");  
                    Synchronized (object) {try {object.wait ();  
                    catch (Interruptedexception e) {e.printstacktrace (); } System.out.println ("Thread end ...").  
            ");  
        }  
        });  
    T.start (); }  
}  

From the code point of view, between the execution thread and the end of the thread, let the thread get the object object as its own object monitor, and then call the object's Wait () method to get it into the waiting state. Then the results of the program running are as follows:

Start execution thread ...
Enter wait state ...
After the program has not been awakened, the "thread end" will no longer be printed, and the program cannot be completed and is in a waiting state.


So from the above theory and practice to analyze, we can draw the following conclusions:

(1) When a thread is running, when it is invoked to hold the Wait () method of the monitor object, the thread first enters the waiting state and releases the monitor object it holds.

(2) If a thread is in the waiting state, then the way to wake it is to open a new thread, through the Notify () or notifyall () way to wake. Of course, the point to note is that the same monitor object must be the same.

(3) While the Sleep () method interrupts the thread, it does not release its own monitor object and remains able to keep the code on after the interruption is complete.

Iii. Notify () and Notifyall ()


After you finish the sleep () and wait () methods, let's talk about the other two methods in the object class that are related to the (). First or through the source of the way to let you first preliminary understanding:

    /** * wakes up a single thread, is waiting on this object ' s * monitor. If any threads are waiting in this object, one of the them * is chosen to be awakened. The choice is arbitrary and occurs the discretion of the implementation. 
     A thread waits on an object ' s * Monitor by calling one of the {@code wait} methods.  * <p> * The awakened thread won't be able to proceed until the current * thread relinquishes the lock On this object. The awakened thread would * compete in the usual manner with any other threads that might is * actively competi Ng to synchronize on this object; For example, the * awakened thread enjoys no reliable privilege or disadvantage in being * "Next thread to" 
     Lock this object. * <p> * This method should to called by a thread, is the owner * 's This object ' s monitor. A thread becomes the owner of the * object ' s monitor in one of three ways:
     * <ul> * <li>by Executing a Synchronized instance method of this object. 
     * <li>by executing the body of a {@code synchronized} statement * This synchronizes on the object. 
     * <li>for objects of type {@code class, by executing a * synchronized static method of that class. 
     * </ul> * <p> * Only one thread in a time can own an object ' s monitor. * * @exception illegalmonitorstateexception If the current thread isn't * The owner of this O 
     Bject ' s monitor. * @see Java.lang.object#notifyall () * @see java.lang.object#wait ()/public final native  void Notify ();

First Look at the Notify () This method, through the reading source we can sum up a few:         (1) When a thread is in the wait () state, it is also waiting for it to be held before the object ' s monitor is released , the Notify () method allows the thread to be active again to rob the object's monitor and wake the thread.         (2) If multiple threads are in a waiting state at the same time, then calling the Notify () method can only randomly wake a thread.         (3) at the same time, only one thread can get the object ' monitor, and then release it for other threads to preempt after execution is complete. Of course, how to make a thread the holder of object ' monitor, I'll explain it in a multithreaded blog.
Next, let's look at the Notifyall () method:

    /** * wakes up all threads that are waiting on this object ' s monitor. 
     A * thread waits on an object ' s monitor by calling one of the * {@code wait} methods. * <p> * The awakened threads won't be able to proceed until the current * thread relinquishes the LOC K on this object. The awakened threads * 'll compete in the usual manner and any other threads that might * is actively compet ing to synchronize on this object; For example, * The awakened threads enjoy no reliable privilege or disadvantage in * being the next thread to 
     Lock this object. * <p> * This method should to called by a thread, is the owner * 's This object ' s monitor. The {@code Notify} method for A * Description of the ways in which a thread can become the owner of * a mo 
     Nitor. * * @exception illegalmonitorstateexception If the current thread isn't * owner of this Object ' s monitor. * @see java.lang.object#notify () * @see java.lang.object#wait ()/public final native Voi   D Notifyall ();
As the name implies, Notifyall () is used to wake up all threads in the waiting state, but note the following: (1) Notifyall () wakes only those threads waiting to preempt the specified object ' monitor, and other threads are not awakened. (2) Notifyall () will only be awakened one by one, not by unity. Because at the same time only one thread can hold the object ' s Monitor (3) Notifyall () is just a random wake-up thread, not an ordered wake. So how to do an orderly awakening is the next issue we want to discuss.

Notify () the idea and realization of realizing ordered awakening

As for the questions raised in the previous section, we can think and discuss them in this section. First of all, in simple terms, what we need to solve is the orderly ordering of multithreading against object ' s monitor. So based on this idea, I'm directly on the code:

public class Mythreadfactory {//thread A is in the waiting state of the flag private Boolean isthreadawaiting;  
    The flag of whether thread B is in wait state private Boolean isthreadbwaiting;  
  
    Whether thread c is in the waiting state of the token private Boolean isthreadcwaiting;  
        Public Mythreadfactory () {isthreadawaiting = true;  
        Isthreadbwaiting = true;  
    Isthreadcwaiting = true;  
  
    /** * Object lock/Private Final object = new Object ();  
            /** * This thread as a wake-up thread/public void Startwakenthread () {Thread t = new Thread (new Runnable () { @Override public void Run () {synchronized (object) {S  
                    Ystem.out.println ("Wake thread starts executing ...");  
                First release thread A Quitthreada ();  
        }  
            }  
        });  
    T.start (); /** * Start thread A/public void Startthreada () {Thread t = new Thread (NEW Runnable () {@Override public void run () {synchronized (object) {  
                    SYSTEM.OUT.PRINTLN ("Thread A begins to wait ..."); try {for (;;)  
                            {if (!isthreadawaiting) break;  
                        Object.wait ();  
                    } catch (Interruptedexception e) {e.printstacktrace ();  
                    } System.out.println ("Thread A Ends ...");  
                    After thread a ends, suspend 2 seconds to free thread B try {thread.sleep (2000);  
                    catch (Interruptedexception e) {e.printstacktrace ();  
                } quitthreadb ();  
        }  
            }  
        });  
    T.start (); /** * Start thread B */public void startthreadb () {ThRead T = new Thread (new Runnable () {@Override public void run () {Synchroni  
                    Zed (Object) {System.out.println ("thread B starts waiting ..."); try {for (;;)  
                            {if (!isthreadbwaiting) break;  
                        Object.wait ();  
                    } catch (Interruptedexception e) {e.printstacktrace ();  
                    } System.out.println ("Thread B ends ...");  
                    After thread B ends, suspend 2 seconds to free thread C try {thread.sleep (2000);  
                    catch (Interruptedexception e) {e.printstacktrace ();  
                } QUITTHREADC ();  
        }  
            }  
        });  
    T.start (); /** * Start thread c */public void StartthreadC () {Thread t = new Thread (new Runnable () {@Override public void run () {  
                    Synchronized (object) {System.out.println ("Thread C starts waiting ..."); try {for (;;)  
                            {if (!isthreadcwaiting) break;  
                        Object.wait ();  
                    } catch (Interruptedexception e) {e.printstacktrace ();  
  
                    } System.out.println ("Thread C ends ...");  
                    try {thread.sleep (1000);  
                    catch (Interruptedexception e) {e.printstacktrace (); System.out.println ("All threads have finished executing.")  
                ");  
        }  
            }  
        });  
    T.start (); /** * Thread A exits wait/private void Quitthreada() {isthreadawaiting = false;  
    Object.notify ();  
        /** * thread B exit wait/private void quitthreadb () {isthreadbwaiting = false;  
    Object.notify ();  
        /** * thread C exit wait/private void Quitthreadc () {isthreadcwaiting = false;  
    Object.notify ();  }  
}
In the above code, I wrote three threads a,b,c used as a waiting thread, and finally awakened the three threads through a wake thread. My idea is this: (1) the Notify () method ensures that only one thread is awakened at a time, but not which thread is to be awakened. (2) in thread a,b,c, add a for or while loop so that it enters an infinite waiting state. This ensures that the Notify () will not wake the thread anyway. (3) set their respective tokens to the A,B,C thread, and if the thread is to be awakened, change its state and jump out of the dead loop, executing the next thread at the end.
Then the main function of the final call is as follows:
    public static void Main (string[] args) {  
        Mythreadfactory factory = new Mythreadfactory ();  
        Factory.startthreada ();  
        FACTORY.STARTTHREADB ();  
        FACTORY.STARTTHREADC ();  
  
        try {  
            Thread.Sleep (3000);  
        } catch (Interruptedexception e) {  
            e.printstacktrace ();  
        }  
        Factory.startwakenthread ();  
    }
Run Result:
Thread A begins to wait ...
Thread B starts waiting ...
Thread C begins to wait ...
Wake thread begins execution
... Thread A ends ...
Thread B ends ...
Thread C ends ...
All Threads finished ...

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.