Home>

On the Java platform, there are three roles for implementing asynchronous calls:caller, bill of lading, real data

A caller is invoking a time-consuming operation,When data cannot be returned immediately,First return a bill of lading.Then after a break time, use the bill of lading to get the real data.

Go to a cake shop to buy cakes,You do n’t need to wait for the cake to be made (assuming it takes a long time), you just need to get a delivery list (to do other things), wait until the cake is done,Just pick up the bill of lading for the cake.

public class main {
  public static void main (string [] args) {
    system.out.println ("main begin");
    host host=new host ();
    data data1=host.request (10, "a");
    data data2=host.request (20, "b");
    data data3=host.request (30, "c");
    system.out.println ("main otherjob begin");
    try {
      thread.sleep (200);
    } catch (interruptedexception e) {
    }
    system.out.println ("main otherjob end");
    system.out.println ("data1 =" + data1.getcontent ());
    system.out.println ("data2 =" + data2.getcontent ());
    system.out.println ("data3 =" + data3.getcontent ());
    system.out.println ("main end");
  }
}

The main class here is equivalent to "customer", the host is equivalent to "cake shop", and the customer ordering cake from "cake shop" is equivalent to "sending a request". The returned data is an instance of futuredata, which is equivalent to picking up the goods. single,Not really "cake." After a period of time (after a period of sleep), call data1.getcontent (), which is to get the execution result by taking the bill of lading.

Take a look below,After the customer orders the cake,What the cake shop did:

public class host {
  public data request (final int count, final char c) {
    system.out.println ("request (" + count + "," + c+ ") begin");
    //(1) create an entity for futuredata
    final futuredata future=new futuredata ();
    //(2) In order to create a realdata entity, start a new thread
    new thread () {
      public void run () {
       //Use count, future, and c in anonymous inner classes.
        realdata realdata=new realdata (count, c);
        future.setrealdata (realdata);
      }
    } .start ();
    system.out.println ("request (" + count + "," + c+ ") end");
    //(3) retrieve the futuredata entity as the return value 
    return future;
  }
}

host ("cake shop") upon request,Mr. became an instance of futuredata of "bill of delivery", and then ordered "cake master" realdata to make a cake,Realdata is equivalent to a thread to make cakes.Then the host returns to the customer only the "bill of delivery" future, not the cake.When the cake is ready,Only the cake master can give the corresponding "bill of delivery" cake, which is future.setrealdata (realdata).

Let ’s take a look at how the cake master made the cake:

Build a string,Contains count c characters, it takes some time to show offense,Used sleep.

public class realdata implements data {
  private final string content;
  public realdata (int count, char c) {
    system.out.println ("making realdata (" + count + "," + c+ ") begin");
    char [] buffer=new char [count];
    for (int i=0;i<count;i ++) {
      buffer [i]=c;
      try {
        thread.sleep (1000);
      } catch (interruptedexception e) {
      }
    }
    system.out.println ("making realdata (" + count + "," + c+ ") end");
    this.content=new string (buffer);
  }
  public string getcontent () {
    return content;
  }
}

Now let's see how the "bill of delivery" future corresponds to the cake "content":

public class futuredata implements data {
  private realdata realdata=null;
  private boolean ready=false;
  public synchronized void setrealdata (realdata realdata) {
    if (ready) {
      return;//Prevent setrealdata from being called more than twice.
    }
    this.realdata=realdata;
    this.ready=true;
    notifyall ();
  }
  public synchronized string getcontent () {
    while (! ready) {
      try {
        wait ();
      } catch (interruptedexception e) {
      }
    }
    return realdata.getcontent ();
  }
}

After customers do their own thing,Will take his own "bill of delivery" to pick up the cake:

system.out.println ("data1 =" + data1.getcontent ());

If the cake is not ready at this time,I had to wait:

while (! ready) {      try {        wait ();      } catch (interruptedexception e) {      }//You can get it after you finish itreturn realdata.getcontent ();

Program analysis

For each request,host will generate a thread,This thread is responsible for generating the "cake" required by the customer. After waiting for a while,If the cake is not ready yet,Customers must also wait.Until "the cake is done", which is future.setrealdata (realdata);Customers can take the cake.

Each thread is only responsible for making the "cake" required by a particular customer. That is, customer a corresponds to cake master a, and customer b corresponds to cake master b. Even if customer b's cake is made first,Customer a can only wait for cake master a to make the cake.in other words,There is no competitive relationship between customers.

Two methods of futuredata class are set to synchronized, in fact, the mutually exclusive relationship between cake master a and customer a,That is, customer a must wait for cake master a to make the cake.To take away,It has nothing to do with whether the cake master b has made the cake.

  • Previous Android desktop component App Widget usage introduction tutorial
  • Next ADSI Error in DirectoryEntry Configuration IIS7: Unknown Error (0x80005000)