JavaAndroid

全面掌握同步、回调、异步回调的使用

2018-05-23  本文已影响55人  文景大大

本文主要解决如何理解同步调用、回调、异步调用的概念及其相互关系,然后从实例的角度来阐述它们的使用方法。

我们知道,软件众多模块之间如果要进行通信,都必须通过相互的接口进行调用,那么如何调用就成了一个问题,现如今主要存在以下三种方式的调用:

一、同步调用

关于同步调用有以下几个基本认知:

同步调用很好理解,下面是一个最基本的示例:

public class Student {
    public void doHomework(){
        System.out.println("student——homework");
    }
}
public class Teacher {  
    public void giveLecture(){
        System.out.println("teacher——lecture");
    }   
    public void assignHomework(Student rose){
        System.out.println("teacher——assign——homework");
        // 同步调用
        rose.doHomework();
    }   
    public void fixHomework(){
        System.out.println("teacher——fix——homework");
    }
}
public class Test {
    public static void main(String[] args) {
        Teacher jack = new Teacher();
        Student rose = new Student();
        jack.giveLecture();
        jack.assignHomework(rose);
        jack.fixHomework();
    }
}

在上述代码中,teacher主动调用了studentdoHomework方法,只有等到该方法执行完成以后,teacher的其它行为才会执行,代码的执行结果如下:

teacher——lecture
teacher——assign——homework
student——homework
teacher——fix——homework

二、回调

关于同步调用有以下几个基本认知:

基于上面的例子,我们来通过代码看一下回调的实现逻辑:

public class Student {
    public void doHomework(Teacher teacher){
        System.out.println("student——homework");
        // 回调teacher中的方法
        teacher.fixHomework();
    }
}
public class Teacher {
    public void giveLecture(){
        System.out.println("teacher——lecture");
    }
    public void assignHomework(Student rose){
        System.out.println("teacher——assign——homework");
        // 调用student的方法时,将自身的引用也传递过去,以实现回调
        rose.doHomework(this);
    }
    public void fixHomework(){
        System.out.println("teacher——fix——homework");
    }
    public void sayGoodbye(){
        System.out.println("teacher——goodbye!");
    }
}
public class Test {
    public static void main(String[] args) {
        Teacher jack = new Teacher();
        Student rose = new Student();
        jack.giveLecture();
        jack.assignHomework(rose);
        jack.sayGoodbye();
    }
}

在上面的例子中,teacher在调用student的方法时,将自身的引用对象也传递过去了,这样student中的该方法就可以在自己认为合适的时候回调teacher中的某个方法,这就是回调,代码的执行结果如下:

teacher——lecture
teacher——assign——homework
student——homework
teacher——fix——homework
teacher——goodbye!

在本例中,使用回调的好处非常明显,teacherfixHomework不需要在main中主动调用,当studentdoHomework结束的时候自动就可以执行了。

三、异步回调

在上面回调的例子中,我们可以看到,它其实还是同步阻塞式的,也就意味着,studentdoHomework没有结束,teacher的后续行为都无法进行,这在异步调用中就可以解决这一问题。

我们还是使用上面的例子,只不过异步的实现需要借助Java的Thread来实现,具体的示例如下:

public class Student {
    public void doHomework(Teacher teacher){
        System.out.println("student——homework");
        // 回调teacher中的方法
        teacher.fixHomework();
    }
}
public class Teacher {
    public void giveLecture(){
        System.out.println("teacher——lecture");
    }
    // 备注一:这里为什么要使用final?
    public void assignHomework(final Student rose){
        System.out.println("teacher——assign——homework");
        // 启动一个线程来实现异步调用
        new Thread(
            new Runnable(){
                @Override
                public void run() {
                    // 备注二:这里为什么要使用Teacher.this而不是this?
                    rose.doHomework(Teacher.this);
                }   
            }
                ).start();
    }
    public void fixHomework(){
        System.out.println("teacher——fix——homework");
    }
    public void watchTv(){
        System.out.println("teacher——watchTv");
    }
}
public class Test {
    public static void main(String[] args) {
        Teacher jack = new Teacher();
        Student rose = new Student();
        jack.giveLecture();
        jack.assignHomework(rose);
        jack.watchTv();
    }
}

在这个例子中,teacher在assignHomework的时候启动了线程来实现异步地调用student的doHomework,然后不管doHomework是否完成都继续往下执行,然后student的doHomework完成以后才回调,这就实现了异步回调,代码的执行结果如下:

teacher——lecture
teacher——assign——homework
teacher——watchTv
student——homework
teacher——fix——homework

最后要需要对代码中的备注进行说明:

关于内部类的详细说明和用法,在另一篇文章《内部类有哪些?它们存在的意义是什么?》中有非常详细的介绍。

上一篇 下一篇

猜你喜欢

热点阅读