zoukankan      html  css  js  c++  java
  • 回调



    Coding中经常遇到回调,大概知道是什么作用但没有去理解其原理,导致后期遇到类似问题还是很懵,现在就来学习一下


    1. 回调

    回调简单而言:在一个类(A)的方法(a)中调用另一个类(B)的方法(b),当方法(b)执行完之后就调用类(A)中的方法(c),这就是回调的过程,是不是很简单?简单分析可以知道一个类(A)持有另一个类(B)的引用,方法(c)就叫做回调函数,画成UML图就如下所示:




    2. 同步回调

    这里模拟一个情景,小狗邀请小猫出去玩,而小猫要午睡,所以小狗要等到小猫睡醒了才一起出去玩,要实现的功能是小猫睡醒了回调通知小狗


    其主要对象有:

    • 回调接口
    • 回调实现类
    • 被调用者

    2.1 回调接口

    public interface Callback {
    	
        // 回调函数
    	public void callback();
    
    }
    

    2.2 回调实现类

    public class Dog implements Callback {
    	
        // 持有类B的引用
    	private Cat cat;
    	public void setCat(Cat cat) {
    		this.cat = cat;
    	}
    	
    	public void playOutside(){
    		System.out.println("Dog:invite cat to play outside,but cat is sleep");
    		cat.sleep(this);    // 重点在此,方法参数为回调类
    	}
    	
    	@Override
    	public void callback() {
    		System.out.println("Dog:Let's go");
    	}
    	
    }
    

    2.3 被调用者

    public class Cat {
    	
    	public void sleep(Callback callback){
            System.out.println("Cat:i need to sleep");
    		System.out.println("Cat:i am sleeping");
    		System.out.println("Cat:i am sleeping");
    		System.out.println("Cat:i am waking up");
    		callback.callback();  // 在此回调
    	}
    }
    

    2.4 测试

    public class test {
    	
    	public static void main(String[] args) {
    		
    		Dog dog = new Dog();
    		Cat cat = new Cat();
    		
            // 设置引用
    		dog.setCat(cat);
    		
            // 邀请小猫出去玩
    		dog.playOutside();
    	}
    }
    
    Dog:invite cat to play outside
    Cat:i need to sleep
    Cat:i am sleeping
    Cat:i am sleeping
    Cat:i am waking up
    Dog:Let's go
    




    3. 异步回调

    回调最重要体现在异步上,在上面的例子中,小狗在等小猫醒来的过程中是被阻塞不能执行其他任务的,所以异步回中小狗在等小猫过程中可以干其他事情,等小猫醒了再去执行出去玩这个任务,提高了执行效率


    3.1 改造Dog类

    public class Dog implements Callback {
    	
    	private Cat cat;
    	public void setCat(Cat cat) {
    		this.cat = cat;
    	}
    	
    	public void playOutside(){
    		System.out.println("Dog:invite cat to play outside");
    		new Thread( () -> {
    				try {
    					cat.sleep(this);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    		}).start();
    	}
    	
    	public void watchTV(){
    		System.out.println("Dog:i am watching TV");
    	}
    	
    	public void playGame(){
    		System.out.println("Dog:i am playing Game");
    	}
    	
    	@Override
    	public void callback() {
    		System.out.println("Dog:Let's go");
    	}
    }
    

    3.2 改造Cat类

    public class Cat {
    	
    	public void sleep(Callback callback) throws InterruptedException{
    		System.out.println("Cat:i need to sleep");
    		System.out.println("Cat:i am sleeping");
    		System.out.println("Cat:i am sleeping");
    		Thread.sleep(5000);		// 猫说完就睡了5秒
    		System.out.println("Cat:i am waking up");
    		callback.callback();	// 猫醒来就告诉狗
    	}
    }
    

    3.3 异步回调测试

    public class test {
    	
    	public static void main(String[] args) throws InterruptedException {
    		
    		Dog dog = new Dog();
    		Cat cat = new Cat();
    		dog.setCat(cat);
    		
            // 小狗邀请小猫
    		dog.playOutside();
    		
    		// 这里睡1秒为了让小狗邀请小猫这个动作执行完
    		Thread.sleep(1000);
    		
            // 小猫午睡期间小狗执行了其他任务
    		dog.watchTV();
    		dog.playGame();
    		
    	}
    }
    
    Dog:invite cat to play outside
    Cat:i need to sleep
    Cat:i am sleeping
    Cat:i am sleeping
    Dog:i am watching TV
    Dog:i am playing Game
    Cat:i am waking up
    Dog:Let's go
    


  • 相关阅读:
    东南大学2021年数学分析考研试卷
    东南大学2021年高等代数考研试卷
    东南大学2021年高等代数考研试卷
    东华大学2021年数学分析考研试卷
    东华大学2021年高等代数考研试卷
    [Oracle 工程师手记]探究 Oracle PDB Application Container (二)
    [Oracle 工程师手记]探究 Oracle PDB Application Container (一)
    Jenkins Extended choice parameter和Active Choices param 之Groovy Script使用
    C#异步调用,成功回调中更新界面(线程间操作无效)
    C#使用非托管 DLL 函数
  • 原文地址:https://www.cnblogs.com/Howlet/p/12325363.html
Copyright © 2011-2022 走看看