唐僧喜欢小龙女

导航

自定义一个异步回调的例子

1、异步回调的理解

/**
*
* 一、什么是callBack?callBack 怎么理解
* 拆成 call和back 字面意思是稍后回呼,正式的意思是回调或者回呼
* 二、什么是异步
* A流程请求第三方接口B之后,不需要等待B应答,而是继续执行A剩余的逻辑,这样A的操作叫异步处理。
* 例如发消息也是一个异步
* 三、什么是异步回调
* 主程序开启一个线程来进行异步操作,异步操作花的时间、成功还是失败都不影响主调程序的继续向下执行。
* 异步回调是:主线程给异步线程传一段逻辑代码,这个逻辑会在异步线程里要用到,但不是说异步线程里马上就用,
* 可能是异步线程执行完自身其他的逻辑后再用。这就是callback的逻辑。
* 我做完了我的任务再后在按你说的来,这就是 call (your instruction) back after I’m done 的意思吧。
* 四、异步回调具体的举例说明
* 设想一个情景,A是处理业务的一个步骤,A需要解决一个问题,这时候A可以问B,让B来告诉A答案,
* 这期间,A可以继续做自己的事情,而不用因为B做的事而阻塞。于是,我们想到给B设置一个线程,让B去处理耗时的操作,
* A的耗时逻辑在 A中写好,然后传给B 。B可以立即执行或者 在B执行完自身的逻辑好调用A 的逻辑(一般是一个Runnalbe接口或者Callback 接口)
* 这就是回头调用函数,简称回调函数
*
* 五、回调函数的错误理解
* 回调函数不是异步线程里面主动调用主线程。
*
*/

2、具体的例子 

2.1 定义一个接口

public interface CallBackBody {

    void onSuccess(Object context);

    void onFailure(Object context);

    public abstract void execute(Object context) throws Exception;

}

2.2 回调的工具类

public class CallBackTask {

    private CallBackBody body;

    public CallBackTask(CallBackBody body) {
        this.body = body;
    }

    public void start(final Object context) {
       final CallBackBody callBackBody = body;
        final Thread t = new Thread(new Runnable() {

            public void run() {
                try {
                    callBackBody.execute(context);
                } catch (Exception e) {
                    e.printStackTrace();
                    callBackBody.onFailure(context);
                }
                callBackBody.onSuccess(context);
            }
        });
        t.start();
    }
    
}

2.3 接口的实现类

@Component
public class CallbackDemo implements CallBackBody {


    @Autowired
    private RestTemplate restTemplate;


    @Override
    public void onSuccess(Object context) {
        System.out.println("\n异步任务执行成功了");
        System.out.println("\n异步任务执行完成!当前线程是"+Thread.currentThread().getName());

    }

    @Override
    public void onFailure(Object context) {
        System.out.println("异步任务执行失败了");
    }

    @Override
    public void execute(Object context) throws Exception {
        System.out.println("\n正在执行耗时操作...");
        System.out.println(context);
        restTemplate.postForObject("http://localhost:8004/test1",null,String.class);
        System.out.println("\n异步任务执行完成!当前线程是"+Thread.currentThread().getName());
    }
}

3、发起调用

@RestController
public class AsyncController {
    @Autowired
    CallbackDemo callbackDemo;

    @RequestMapping("/test")
    public void test(){
        System.out.println("准备开始执行异步任务...");
        final Object context = "上下文信息";
        //开始异步调用
        new CallBackTask(callbackDemo).start(context);
        System.out.println("\n异步任务让别的线程执行了,当前线程是"+Thread.currentThread().getName()+"我要执行别的任务了,异步任务执行完了会告诉主线程的");
    }
}

 

posted on 2021-10-04 20:46  与时具进&不忘初心  阅读(71)  评论(0)    收藏  举报