Java multi threaded implementation of asynchronous invocation methods

  • 2020-04-01 04:13:06
  • OfStack

In the JAVA platform, there are three roles that implement asynchronous invocation: the caller's bill of lading     Real data

A caller returns a bill of lading when a time-consuming operation cannot return data immediately, and then retrieves the real data with the bill of lading after a period of time.
You don't need to wait for the cake to be made (assuming it takes a long time to make), you just need to get a bill of lading (to do something else), and when the cake is ready, you can pick it up with the bill of lading.


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", the customer orders cake to "cake shop" is equivalent to "send a request", the data returned is an instance of FutureData, is equivalent to a bill of lading, not the real "cake". After some time (after some sleep), call data1.getcontent (), which means take the bill of lading and get the execution results.

Here's a look at what the bakery did after the customer ordered the cake:


public class Host {  
  public Data request(final int count, final char c) {  
    System.out.println("request(" + count + ", " + c + ") BEGIN");  
    //(1) establish the entity of FutureData
    final FutureData future = new FutureData();  
    //(2) to establish the entity of RealData, 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) fetch the FutureData entity as the return value
    return future;  
  }  
} 

  After receiving the request, Mr. Host (" cake shop ") becomes the instance future of "bill of lading" FutureData, and then orders "cake maker" RealData to make the cake. RealData is equivalent to starting a thread to make the cake. The host then returns to the customer only the bill of lading future, not the cake. When the cake is ready, the baker can give the corresponding "bill of lading" cake, which is future.setrealdata (realdata).

Here's how the cake maker makes it:

To create a string that contains count and c characters, and to show that breaking the law takes some time, sleep is used.


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 bill of lading 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();  
  }  
}

    When the customer has finished his work, he brings his "bill of lading" to pick up the cake:


System.out.println("data1 = " + data1.getContent()); 

If the cake is not ready, we have to wait:


while (!ready) {  
      try {  
        wait();  
      } catch (InterruptedException e) {  
      }  
//You can't get it until it's ready
return realdata.getContent(); 

      Program analysis

      For each request, the host generates a thread that generates the "cake" the customer wants. After waiting for some time, if the cake is not ready, the customer must wait. Until the "cake is done," which is future.setrealdata (realdata); After the execution, the customer can take the cake.

    Each thread is solely responsible for making the "cake" that a particular customer needs. So customer A corresponds to baker A, and customer B corresponds to baker B. Even if customer B's cake is made first, customer A has to wait for baker A to make it. In other words, there is no competition between customers.

    The two methods of FutureData are set to synchronized. In fact, there is A mutually exclusive relationship between cake chef A and customer A, that is, customer A must wait for cake chef A to finish the cake before taking it away. It has nothing to do with whether cake chef B has finished the cake or not.

The content of this article is all over, the code is simple, I hope to learn Java multi-threaded asynchronous call to help, thank you.


Related articles: