Before we look at callbacks, we must understand what synchronous versus asynchronous calls are. The two concepts are easy to understand. Synchronous and asynchronous are relative to time:

  • Synchronous invocation: Only one thing can be done at a time
  • Asynchronous invocation: Multiple things can be done at the same time, usually through the following two methods:
    • Multithreading: Start a single thread of execution for methods that need to block
    • Callback: A callback is used to notify the main thread that the execution is complete or obtain the execution result

Multithreading everyone can understand a look, then what is the callback?

1. Callback mechanism

Callbacks are a means of implementing asynchronous calls for asynchronous communication services, which can be subdivided into the following types:

1.1 Basic callback

The basic form is as follows:

Object A ---- b.bb (A) -----> Object B// call B fb() and pass in A itself (this)A object <----- a.fa ()------ B object// B can call A directly, fa() is the callback method
Copy the code

1.2 Interface Callback

Interface-based callbacks: Strong coupling occurs if you can only pass type A to fb(), so fb() is usually passed an interface that A implements

AImpl ---- b.bb (IA) -----> b object// IA is the abstract interface, AImpl is the implementation class of IAAImpl <----- ia.fa ()------ B objectCopy the code

1.3 Asynchronous Callback

The asynchronous callback gives the b.bb () method a separate thread to execute

  • Usage scenario: When A calls A method of B and the method blocks or takes A long time, the method can be made an asynchronous call
  • Asynchronous communication: Communicates with user A through the callback mechanism
AImpl ---- b.bb (IA) -----> b object// b(IA) executes on a separate threadAImpl <----- ia.fa ()------ B objectCopy the code

2. Code examples

Concept said, now on to the code…

2.1 Synchronous Invocation

Programmer now needs to do a few things:

  1. Code all day (code)
  2. Upload today’s code to Github (Upload code)
  3. Note the completion date (note the date of completion)

Here we use the program to achieve: the program is a total of three classes:

  • Programmer (Programmer)
  • Github (The Github class is used to save code submitted by code farmers)
  • TestDemo (for testing and displaying results)

As follows:

public class Programmer {

    public void code(a){                       
        System.out.println("coding");      / / step1. Write the code
        new Github().push();               //step2. Submit the code
        recordToday();                     //step3. Record the date
    }

    public void recordToday(a){
        System.out.println("i'm done " + newDate()); }}Copy the code
// Only upload code
public class Github {
    public void push(a){
        System.out.println("git push"); }}Copy the code
// Let Programmer work
public class TestDemo {
    public static void main(String args[]){
        Programmer p = newProgrammer(); p.code(); }}Copy the code

The result is as follows:

2.2 Basic callback

Give the miserable programmer a way out and leave it to the Github class to take care of things like date: recodeToday ().

In other words, after the Github push () function is completed, the Github class calls the recodeToday () method of the Github class, rather than calling it itself, with minor changes

// A
public class Programmer {
    public void code(a){
        System.out.println("coding");
        new Github().push(this);   // B.fb(this)
        // there is no step3, the coder does not call the recordToday() method himself.
    }

    // a.fa (), callback method
    public void recordToday(a){
        System.out.println("i'm done " + newDate()); }}Copy the code
// B
public class Github {
    public void push(Programmer p ){   // Push has more Programmer classes
        System.out.println("git push");
        p.recordToday();    // Perform the callback}}Copy the code

The final execution result remains unchanged

2.3 Interface Callback

If GitHub’s push method is now not only Programmer but also Teacher and Student, why should it be reloaded? The best approach is to push dependent interfaces

// IA, callback interface
public interface RecodeInterface {
    public void recode(a);
}
Copy the code
// B
public class Github {
    public void push(RecodeInterface r ){ // Depend on the interface
        System.out.println("git push");
        r.recode(); // a.fa (), perform the callback}}Copy the code
// AImpl implements the interface
public class Programmer implements RecodeInterface{
    public void code(a){
         System.out.println("coding");
         new Github().push(this); // B.fb(A)
     }
    
    @Override
    public void recode(a) { // The callback function
        System.out.println("Programmer done " + newDate()); }}Copy the code
public class Student {
    public void code(a){
        System.out.println("coding");
        new Github().push(new StudentRecodeToday());
    }
	
    // AImpl can also be abstracted as a separate inner class
    public class StudentRecodeToday implements RecodeInterface{
        @Override
        public void recode(a) {
            System.out.println("Student done "+ newDate()); }}}Copy the code

2.4 Asynchronous Callback

// IA, callback interface
public interface mycallback {
    void onData(Object message); // Normal processing
    void onError(Exception e); // Exception handling
}
Copy the code
// AImpl implements the back interface
public class Client implements mycallback{
    int count=0;
    @Override
    public void onData(Object message) {
        count++;
        System.out.println("received message:"+message.toString());
    }
 
    @Override
    public void onError(Exception e) {
        System.out.println("error!");
    }
    public void send(String message){
        // Asynchronous callback core!! Start a separate thread for B.bb (IA)
        Thread thread=new Thread(new Server(Client.this,message)); thread.start(); }}Copy the code
// B
public class Server implements Runnable{
    mycallback c;
    Object message;
    public Server(mycallback cl,Object o){
        c=cl;
        message=o;
    }
    @Override
    public void run(a) {
        try {
            c.onData(message+" after server"); // Perform the callback
        }catch(Exception e){ c.onError(e); }}}Copy the code

Start the class

public class Work{
 
    public static void main(String[] args){
        Client c1=new Client();
        c1.send(hello);
        System.out.println("do others..."); }}Copy the code

The results of

do others...
received message:hello
Copy the code