Java multi-threaded notes three (thread communication wait/notify/notifyall/sleep/yield/join) __java

Source: Internet
Author: User
Tags object object thread class
one, Wait (), notify (), Notifyall () 1, signal volume

One of the easiest ways to communicate between threads is to set the semaphore in a variable of a shared object. Thread A sets the Boolean member variable hasdatatoprocess to true in a synchronized block, and thread B reads hasdatatoprocess This member variable in the synchronization block. The following example uses a signal-holding object and provides set and check methods:

public class mysignal{
  protected Boolean hasdatatoprocess = false;
  Public synchronized Boolean hasdatatoprocess () {return
    this.hasdatatoprocess;
  }
  Public synchronized void Sethasdatatoprocess (Boolean hasData) {
    this.hasdatatoprocess = hasData;
  }
}

Threads A and B must obtain a reference to a Mysignal shared instance for communication. If they hold references that point to different mysingal instances, they will not be able to detect each other's signals.

See below for an example, the thread B preparing to process the data is waiting for the data to become available. In other words, it is waiting for a signal from thread A, which causes hasdatatoprocess () to return true. Thread B runs in a loop to wait for this signal:

protected Mysignal sharedsignal = ...
...
while (!sharedsignal.hasdatatoprocess ()) {
  //do nothing ... busy waiting
}

This situation is called busy waiting , it does not make efficient use of the CPU that is running the waiting thread, unless the average wait time is very short, it is wiser to let the waiting thread go to sleep or not to run until it receives the signal that it waits. 2, waiting and waking

Java has a built-in wait mechanism to allow threads to become inactive when waiting for a signal. The Java.lang.Object class defines three methods, wait (), notify (), and Notifyall () to implement this waiting mechanism.
Once a thread calls the wait () method of any object, it becomes waiting until another thread calls the Notify () method of the same object (or sets a time parameter that wakes up automatically after the timeout). The following is a modified version of Mysingal-using the mywaitnotify of Wait () and notify ():

public class monitorobject{} public

class mywaitnotify{
  monitorobject mymonitorobject = new Monitorobject ();
  public void dowait () {
    synchronized (mymonitorobject) {
      try{
        mymonitorobject.wait ();
      } catch ( Interruptedexception e) {...}
  }} public void Donotify () {
    synchronized (mymonitorobject) {
      mymonitorobject.notify ();
    }
  }
}

Calling dowait () causes the thread to enter a wait state, while the wakeup wait thread invokes donotify ().

As you can see, in order to invoke wait () or notify (), the thread must first obtain the lock on that object. In other words, the thread must call Wait () or notify () in the synchronization block. This is mandatory. A thread cannot invoke wait (), notify (), or notifyall () if it does not hold an object lock. When you call them, the JVM first checks to see if the current thread is the owner of the lock, and does not throw the illegalmonitorstateexcept exception.

note that the invocation of Wait () and notify () are in the synchronization block and have the same monitor object, so the object calls a method without blocking any other methods. The answer is no. Once the thread invokes the Wait () method, it frees the lock on the monitor object that it holds, enters the waiting state until the other thread calls the Notify () method on the object, or times out.

notify () and Notifyall () are methods that the object object uses to inform the thread that is waiting for the object. The difference is:
Notify will randomly wake up a wait state thread and make it acquire a lock on the object without disturbing the other threads, and for the rest of the thread, they are waiting for the notify signal and waiting.
Notifyall wakes all waiting threads so that their state changes from waiting notify to waiting locks, and once the object is unlocked, they compete for the lock, and eventually only one thread can get the object lock and execute the code, and the other threads execute sequentially. 3, missing signals and false wakes

When notify () and Notifyall () are invoked, it is possible that no threads are in the waiting state. That is, if a thread calls notify () before the notified thread calls Wait (), the waiting thread misses the signal. This may cause the waiting thread to wait forever and not wake up.
To avoid signal loss , use a variable to save whether it has been notified. Before notify, set yourself to have been notified. Check this variable (execute wait without notice) before calling the (), and after waiting, set yourself up without being notified, and you will be notified.

For inexplicable reasons, threads may wake up without invoking notify () and Notifyall (). This is called false Awakening (spurious wakeups).
To prevent false awakening , the member variable that holds the signal is checked in a while loop, not in the IF expression. Such a while loop resembles a spin lock (if the Donotify method is not invoked for a long time, the Dowait method spins and the CPU consumes too much). The awakened thread spins until the condition in the spin lock (while loop) changes to false. The following code shows this:

public class mywaitnotify3{

  monitorobject mymonitorobject = new Monitorobject ();
  Boolean wassignalled = false;

  public void dowait () {
    synchronized (mymonitorobject) {while
      (!wassignalled) {
        try{
          Mymonitorobject.wait ();
         } catch (Interruptedexception e) {...}
      }}
      Clear signal and continue running.
      wassignalled = false;
    }
  }

  public void Donotify () {
    synchronized (mymonitorobject) {
      wassignalled = true;
      Mymonitorobject.notify ();}}
two, sleep (), yield (), join ()

The purpose of the 1,sleep () method is to have the current thread suspend the specified time (in milliseconds). What you need to be aware of is the difference between the wait method. The simplest difference is that the wait method relies on synchronization, and the sleep method can be invoked directly. The deeper difference is that the sleep method only temporarily let the CPU's execution power, does not release the lock. The wait method needs to release the lock.
Note: Sleep () is a static method. This means that only the current thread is valid, and a common mistake is to call T.sleep (), where T is a thread different from the current thread. Even the execution of T.sleep () is also the current thread entering sleep rather than the t thread. The sleep () and yield () methods of the thread class are static, and they will run on the currently executing thread, so it makes no sense to raise these methods on other waiting-state threads.

The purpose of the 2,yield () method is to suspend the current thread so that other threads have an opportunity to execute. Yield cannot specify the time of the pause, and it does not guarantee that the current thread will stop immediately (after the current thread has conceded, it may have competed to the lock, and then continues to execute).

The effect of the 3,join () method is that the parent thread waits for the child thread to finish execution before executing, in other words, merging the concurrent threads into sequential execution threads. If you execute Test.join () in the current main thread, main will be blocked until test is complete (similar to the queue).
The Join method is implemented by the wait method, and if the join thread is still executing, the current thread is blocked until the join thread completes and the current thread executes. One thing to note, however, is that the join only calls the Wait method, but there is no corresponding notify method, because the thread's start method does the appropriate processing, so when the join's threads are completed, the main process is automatically awakened to continue.

The sleep (), yield (), join () three methods act as threads for communication, and they are in the thread class. However, the Wait (), notify (), Notifyall () method that implements the thread communication is not located in the thread class, but in the object class.
Because these three methods are to manipulate the lock, the lock is part of all objects, so that every class in Java has a basic method for communicating between threads. We can only invoke the wait (), notify (), Notifyall () method in either the synchronous control method or the synchronization control block, regardless of whether the class inherits the thread class or implements the Runnable interface. The sleep () method can be invoked in an asynchronous control method because it does not have to manipulate the lock.
In fact, calling the Wait (), notify (), Notifyall () method in an asynchronous control method can be compiled, but the runtime reports a illegalmonitorstateexcept exception.



Reference from: Concurrent programming Network-thread communication
Java Concurrent Programming: Collaboration between threads (Wait/notify/sleep/yield/join)

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.