Summary!!! Summary!!! java callback and future mode

I always forget that I write the actual things directly here, and see other blogs are class diagrams, text descriptions, and code descriptions directly here.

Question: What is a callback

callback, callback. There must be a call before there is a callback between the caller and the callee. So in Baidu Encyclopedia it is like this:

There are always certain interfaces between software modules . From the way of calling, they can be divided into three categories: synchronous calls, callbacks and asynchronous calls .

The callback is a special kind of call, and the three ways are a little different.

1. Synchronous callback , that is, blocking, one-way .

2. Callback , that is, bidirectional (similar to two gears of a bicycle).

3. Asynchronous call , that is, notification through asynchronous message .

1. Synchronous call

Directly go to the code b method to call the a method

package java.lang;
/**
 * @author: zhangzeli
 * @date 16:02 2018/4/20
 * <P></P>
 */
public class Test {
    public String a(){
        System.out.println("i am a");
        return "a";
    }
    public String b(){
        a();
        System.out.println("i am b");
        return "b";
    }
}

2. Callback , that is, bidirectional (similar to two gears of a bicycle).

Next, let's take a look at the code example of the callback. The code simulates such a scenario: the teacher asks the student a question, and the student answers the teacher after thinking. First define a callback interface, there is only one method tellAnswer(int answer), that is, the student tells the teacher to answer after thinking:

/**
 * 回调接口
 */
public interface Callback {
    public void tellAnswer(int answer);
}

Define a teacher object that implements the Callback interface:

/**
 * 老师对象
 */
public class Teacher implements Callback {
    private Student student;
    
    public Teacher(Student student) {
        this.student = student;
    }
    public void askQuestion() {
        student.resolveQuestion(this);
    }
    @Override
    public void tellAnswer(int answer) {
        System.out.println("知道了,你的答案是" + answer);
    }
    
}

The teacher object has two public methods:

  1. Callback interface tellAnswer(int answer), that is, what the teacher has to do after the student answers the question
  2. Ask the question method askQuestion(), that is, ask questions to students

Then define a student interface. Of course, the student solves the problem, but receives a Callback parameter, so that the student knows who to report to when the problem is solved:

/**
 * 学生接口
 */
public interface Student {
    public void resolveQuestion(Callback callback);
}

Finally, define a specific student called Ricky:

/**
 * 一个名叫Ricky的同学解决老师提出的问题
 */
public class Ricky implements Student {

    @Override
    public void resolveQuestion(Callback callback) {
        // 模拟解决问题
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            
        }
        // 回调,告诉老师作业写了多久
        callback.tellAnswer(3);
    }

}

Writing a test class is relatively simple:

/**
 * 回调测试
 */
public class CallbackTest {

    @Test
    public void testCallback() {
        Student student = new Ricky();
        Teacher teacher = new Teacher(student);
        
        teacher.askQuestion();
        
    }
    
}

code analysis

Analyze the above code, I have made two layers of abstraction here:

(1) Abstract the teacher

  • After abstracting the teacher, for the students, there is no need to care which teacher asked me the question, as long as I get the answer according to the question asked, and then tell the teacher who asked the question, even if the teacher changes Again, it has no effect on my students

(2) Abstract the students

  • After abstracting the students, it is very flexible for the teacher, because the teacher may not ask questions to one student, but may ask three students Ricky, Jack, and Lucy at the same time, so that the member variable Student can be changed to List< Student>, so you can traverse the Student list to ask questions when asking questions, and then get the answer of each student.

This example is a typical example of the role of the interface. The reason why I say this is because I think that some friends may not understand the benefits of the interface. Friends who don't understand the benefits of the interface can focus on this example to understand more.

To sum up, the core of the callback is that the callback party passes itself, that is, this to the caller , so that the caller can tell the callback party what it wants to know after the call is completed. Callback is an idea and a mechanism. As for how to implement it, how to implement the callback elegantly and with high scalability through code, it depends on the developer's personal level and the developer's understanding of the business. .

In the above example, some people may ask the following questions:

What kind of callback do I need to use in this example? Using a synchronous call method, wouldn't it be better for the student object to directly return the answer to the teacher object after answering the question?

There is no problem in raising this question, and it can be understood from two perspectives.

    First, what if teachers don’t just want answers from students? Maybe this teacher is a teacher who prefers to listen to students' problem-solving ideas. Before getting the students' answers, the teacher wants to know the students' names and students' problem-solving ideas. Of course, some people can say, then I can define an object, which adds The names of the students and their problem-solving ideas are not good. There are two problems with this statement in my opinion:

(1) If the teacher wants more and more data, the returned object will become larger and larger, and the callback can be used to separate the data, and put a batch of data in the callback method for processing. As for which data depends on the specific It depends on the business. If you need to increase the return parameter, you can directly add it in the callback method.

(2) Unable to solve the problem that the teacher hopes to get the student's name, and the student's problem-solving idea precedes the student's answer

Therefore, I think it is not necessary to use callbacks to simply return a result, but synchronous calls can be used directly. However, if there are multiple data to be processed and the data is prioritized , using callbacks will be a more appropriate choice, giving priority to processing The data is processed first in the callback method.

Another angle of understanding is more important, that is, the synchronous callback and asynchronous callback mentioned in the title . The example is an example of a synchronous callback, which means that the teacher asks Ricky a question, Ricky gives the answer, the teacher asks the next classmate, and after getting the answer, he continues to ask the next classmate. This is a normal scenario, but if I change the scenario to one time:

The teacher didn't want to ask questions like One-By-One, but asked five students, Ricky, Mike, Lucy, Bruce, and Kate at the same time, and let the students think for themselves. Whoever thinks well can just tell the teacher the answer directly.

This scenario is equivalent to saying that after students have finished thinking about the problem, there must be a way to tell the teacher, there are two solutions:

  1. Using the Future+Callable method to wait for the execution result of the asynchronous thread is equivalent to a variant of the synchronous call, because its essence is that the method returns a result, that is, the student's answer
  2. Using asynchronous callback, students can answer the question and call the callback interface method to tell the teacher the answer. Since the teacher object is abstracted into the Callback interface, the scalability of this approach is very good. As mentioned before, even if the teacher changes again and again, for the students, the only concern is to call the Callback interface Just send back the necessary information

Let's talk about asynchronous callback Callback, and future mode . The solution is given later in this article.

3. Asynchronous callback---Asynchronous callback in CS (java case)

For example, a scenario is simulated here: the client sends msg to the server, and after the server processes it (5 seconds), it calls back to the client to notify the successful processing. code show as below:

    Callback interface class:

/**
 * 回调模式-回调接口类
 */
public interface CSCallBack {
    public void process(String status);
}

    Mock client:

/**
 * 回调模式-模拟客户端类
 */
public class Client implements CSCallBack {

    private Server server;

    public Client(Server server) {
        this.server = server;
    }

    public void sendMsg(final String msg){
        System.out.println("客户端:发送的消息为:" + msg);
        new Thread(new Runnable() {
            @Override
            public void run() {
                server.getClientMsg(Client.this,msg);
            }
        }).start();
        System.out.println("客户端:异步发送成功");
    }

    @Override
    public void process(String status) {
        System.out.println("客户端:服务端回调状态为:" + status);
    }
}

    Mock server:

/**
 * 回调模式-模拟服务端类
 */
public class Server {

    public void getClientMsg(CSCallBack csCallBack , String msg) {
        System.out.println("服务端:服务端接收到客户端发送的消息为:" + msg);

        // 模拟服务端需要对数据处理
        try {
            Thread.sleep(5 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("服务端:数据处理成功,返回成功状态 200");
        String status = "200";
        csCallBack.process(status);
    }
}

    Test class:

/**
 * 回调模式-测试类
 */
public class CallBackTest {
    public static void main(String[] args) {
        Server server = new Server();
        Client client = new Client(server);

        client.sendMsg("Server,Hello~");
    }
}

Client: The message sent is: Server, Hello~
Client: Asynchronously sent successfully
Server: The message received by the server is: Server, Hello~

(This simulates the server's data processing time, waiting for 5 seconds)
Server: Data processing is successful, and returns a success status of 200
Client: The server's callback status is:

Analyze the code step by step, the core summary is as follows

1. The interface is used as a method parameter , and its actual incoming reference points to the implementation class

2. In the client's sendMsg method, the parameter is final , because it can be used by a new thread of the inner class . This is where asynchrony comes into play .

3. Call the server's getClientMsg(), and the parameter is passed into the Client itself (corresponding to the first point). The above synchronization callback also said

Confusion: Application Scenarios of Callbacks

  1. Message Mechanism for Windows Platform
  2. Asynchronously calls the WeChat interface, and responds to the business logic according to the WeChat return status.
  3. Filter in Servlet is based on callback function and needs container support.

Supplement:  The difference between Filter (filter) and Interceptor (interceptor) is that the interceptor is based on Java's reflection mechanism and has nothing to do with the container. But it has the same effect as the callback mechanism.

The space here is too long, so that everyone will not see the confused future mode. In the next part, the question above is my < test package on the code cloud >

To be honest, I am facing a particularly big challenge now, and there are more and more things to understand. But I have heard what a teacher said before, and I think it makes sense. When I am upset, write code, write code, write code, Lost love, write code, write code. I don’t know what to do, write code. It can be solved

I qq853089986

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324922785&siteId=291194637