Online explanation of the design pattern of the article is very much, a lot of content, technology are more comprehensive and in-depth than ME! But since study, I still want to carry on the summary! Hope you can get some inspiration from reading this article!

When it comes to concurrent programming, we all think, wow, concurrent programming is really hard! But is that really the case? I don’t think so, a skill comes out, as long as you have the determination to conquer it, then you win. That is, we often say: “Steady, wretched development, don’t wave, WE can win!” In the process of learning, there will certainly be some difficulties, find more people to communicate, mutual progress is a very good way, xiaobian hope you can communicate with xiaobian after reading my summary of the article, it is not a great honor.

What is asynchrony?

Before we talk about design patterns, let me talk about asynchrony, asynchrony and synchronization are opposites, these two concepts are actually not difficult to understand, the key is how synchronization and asynchrony are represented in the program, is what we are most curious, most want to know.

Synchronization: When task A depends on task B, task A can continue to execute task B only after task B is complete, and task A is blocked. Missions either succeed or fail! Just think of us on the phone! Asynchronous: task A call task B, task A, B does not need to wait until the task has been completed the task B just return to A virtual to task A result, makes the task A can continue to do other things, wait until the task B completes then inform the task A (the callback) task or task A initiative to request B to results. Just think about texting!

Second,FutureAsynchronous design pattern

First, I found a graph on the Internet that compares the timing differences between asynchronous and synchronous:

So how do we do that? Post a UML diagram first:

Before going through the examples, I feel the need to mention some prerequisites:

  • 1.notify/waitEvery Java object has these two methods. Calling these two methods must first get the monitorsynchronizedSynchronized block to make the call
  • 2,Producer/consumerModel, in fact, this is optional, mainly do not write inIf (block)callnotify/waitMethod, instead ofwhile

All of my logic comments are interspersed in the code below, if you have a question you’d like to share, comment, comment!

Main.java

package com.wokao66.future; @author: huangjiawei * @author: huangjiawei * @since: April 2, 2018 * @version:$Revision$ $Date$ $LastChangedBy$*/ public class Main {public static void Main (String[] args) throws Exception {/** * Holds a Client object */ Client client = new Client(); */ Data virtualData = client.request() */ Data virtualData = client.request()"I'd like to place an order !!!!"); Thread.sleep(5000); / / try {thread.sleep (5000); {}} catch InterruptedException (e) / * * * I want to get real data now * / String realData = virtualData. GetResultData (); System.err.println("The real numbers are:"+ realData); }}Copy the code

Data.java

package com.wokao66.future; /** * Simple abstraction of returned data (both virtual data and real data must implement this interface) * @author: huangjiawei * @since: April 2, 2018 * @version:$Revision$ $Date$ $LastChangedBy$*/ public interface Data {/** * public interface Data {/** * public interface Data; Let the implementation class decide * @throws Exception */ public Abstract String getResultData() throws Exception; }Copy the code

VirtualData.java

package com.wokao66.future; /** * Virtual data (asynchronously returned to the client) * @author: huangjiawei * @since: April 2, 2018 * @version:$Revision$ $Date$ $LastChangedBy$*/ public class VirtualData implements Data {/** * if you return VirtualData without a reference to RealData, where does your Data come from when a client needs to retrieve RealData? ? */ private RealData realData = null; /** * Default is not ready data! */ private Boolean isReady =false; @param RealData */ public synchronized voidsetRealData(RealData realData) {
		System.err.println("Get lock"); /** ** If I am not ready, I need */if (isReady) {
			return;
		}
		this.realData = realData;
		isReady = true; // I'm ready for notify(); } /** * Override the method of obtaining data * @throws Exception */ @override public synchronized String getResultData() throws Exception {/** * if I haven't injected real data when the client calls, then block */while(! IsReady) {// callwaitYou have to get the lock on the object first, sowait(a); }returnrealData.getResultData(); }}Copy the code

RealData.java

package com.wokao66.future; /** * This class represents your specific business operations, such as retrieving database data * @author: huangjiawei * @since: April 2, 2018 * @version:$Revision$ $Date$ $LastChangedBy$*/ public class RealData implements Data {/** * private StringreadData;
	public RealData(String readThread.sleep(10000); / / try {thread.sleep (10000); / / try {thread.sleep (10000); } catch (InterruptedException e) {} this.readData ="Call name:" + readData + "," + "The realData is: realData";
	}
	@Override
	public String getResultData() {
		return readData; }}Copy the code

Client.java

package com.wokao66.future; /** * indicates our client program! Responsible for initiating call requests * @author: Huangjiawei * @since: April 2, 2018 * @version:$Revision$ $Date$ $LastChangedBy$*/ public class Client {/** * specifies the request name of the Client * @param namereturn*/ public Data request(String name) {/** * declare a VirtualData */ VirtualData VirtualData = new VirtualData(); /** * When you call the request, I silently open a Thread to process the actual operation */ new Thread(new)Runnable() {

			@Override
			public void run() {
				System.err.println("I'm surreptitiously requesting a background fetch operation that may take a long time.");
				System.err.println("I don't care. I'll just return the result to the caller."); RealData realData = new RealData(name); Virtualdata.setrealdata (realData); virtualData.setrealData (realData); } }).start(); // I will return a virtual data to you first, and you can come to fetch the real data after I finish retrieving itreturnvirtualData; }}Copy the code

The results

Order successfully............... I secretly request the background to get data operation, the operation may be executed for a long time I leave it, first return the result to the caller to get the lock real data is: call name: I want to order !!!! , the realData is: realDataCopy the code

Don’t know if you have thought through, above the Main Java String in realData = virtualData. GetResultData (); Is a local object that can only be executed locally, but what about tcp-based network transfers? Can use a push, websocket and other ways, dubbo visual inspection is also possible! By the way, Java EE 7 already supports asynchronous servlets. Check out the documentation for details!

Asynchronous concurrent programming in Java

Asynchronous execution results can take one of two forms:

  • 1. There is a callback after execution
  • 2. No callback after execution

A callback means that the client establishes a Listener, and the server actively calls the callback function of the client after executing an asynchronous Future

No callback is what we saw in the previous example, and we need to ask the server to determine if it has been successful

package com.wokao66.javafuture; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; Public class Test {public static void main(String[] args) {/** * Create a thread pool */ ExecutorService executor = Executors.newFixedThreadPool(1); /** * Create a Task */ Task Task = new Task(); /** * Submit the task to the thread pool */ Future<Integer> result = executor.submit(task); Executor.shutdown (); Thread.sleep(1000); thread.sleep (1000); } catch (InterruptedException e1) { e1.printStackTrace(); } System.out.println("I'm doing something else........");

		try {
			System.out.println("The result of the task is:" + result.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}

	}
}

class Task implements Callable<Integer> {

	@Override
	public Integer call() throws Exception {
		System.out.println("The child thread is evaluating."); /** * Thread. Sleep (10000);return100; }}Copy the code

The execution result

The child thread is calculating and I'm doing something else........ The result of the task is 100Copy the code

Java can also create tasks using FutureTask, which implements both Runnable and Callable interfaces.

Thanks for reading!