软件模块之间老是存在着必定的接口,从调用方式上,能够把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种相似消息或事件的机制,不过它的调用方向恰好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系很是紧密,一般咱们使用回调来实现异步消息的注册,经过异步调用来实现消息的通知。同步调用是三者当中最简单的,而回调又经常是异步调用的基础
回调你能够这样来理解:java
A发送消息给B,B处理好A要求的事情后,将结果返回给A,A再对B返回的结果来作进一步的处理。异步
找到一个利用回调配合异步调用的很不错的例子,来源于http://kt8668.iteye.com/blog/205739 函数
A、 回调的实现this
/** * 回调接口 * @author KOOK * */ public interface CallBack { /** * 执行回调方法 * @param objects 将处理后的结果做为参数返回给回调方法 */ public void execute(Object... objects ); }
B、 消息的发送者spa
/** * 简单本地发送异步消息的类 * @author KOOK * */ public class Local implements CallBack,Runnable{ /** * 远程接收消息的类,模拟point-to-point */ private Remote remote; /** * 发送出去的消息 */ private String message; public Local(Remote remote, String message) { super(); this.remote = remote; this.message = message; } /** * 发送消息 */ public void sendMessage() { /**当前线程的名称**/ System.out.println(Thread.currentThread().getName()); /**建立一个新的线程发送消息**/ Thread thread = new Thread(this); thread.start(); /**当前线程继续执行**/ System.out.println("Message has been sent by Local~!"); } /** * 发送消息后的回调函数 */ public void execute(Object... objects ) { /**打印返回的消息**/ System.out.println(objects[0]); /**打印发送消息的线程名称**/ System.out.println(Thread.currentThread().getName()); /**中断发送消息的线程**/ Thread.interrupted(); } public static void main(String[] args) { Local local = new Local(new Remote(),"Hello"); local.sendMessage(); } public void run() { remote.executeMessage(message, this); } }
C、 远程消息的接收者线程
/** * 这个类至关于你的同窗 */ public class Remote { /** * 处理消息 * @param msg 接收的消息 * @param callBack 回调函数处理类 */ public void executeMessage(String msg,CallBack callBack) { /**模拟远程类正在处理其余事情,可能须要花费许多时间**/ for(int i=0;i<1000000000;i++) { } /**处理完其余事情,如今来处理消息**/ System.out.println(msg); System.out.println("I hava executed the message by Local"); /**执行回调**/ callBack.execute(new String[]{"Nice to meet you~!"}); //这至关于同窗执行完以后打电话给你 } }
回调的好处之一:摒弃了继承抽象类方式的回调方式更加简便灵活 code
来源于 http://hellosure.iteye.com/blog/1130176orm
public abstract class B{ public void execute(){ getConnection(); doCRUD(); releaseConnection(); } public abstract void doCRUD(); public void getConnection(){ System.out.println("得到链接..."); } public void releaseConnection(){ System.out.println("释放链接..."); } } public class A extends B{ public void doCRUD(){ System.out.println("执行add操做..."); } public void add(){ doCRUD(); } } public class C extends B{ public void doCRUD(){ System.out.println("执行delete操做..."); } public void delete(){ doCRUD(); } }
若是改成回调实现是这样的blog
interface CallBack{ public void doCRUD(); } public class HibernateTemplate { public void execute(CallBack action){ getConnection(); action.doCRUD(); releaseConnection(); } public void add(){ execute(new CallBack(){ public void doCRUD(){ System.out.println("执行add操做..."); } }); } public void delete(){ execute(new CallBack(){ public void doCRUD(){ System.out.println("执行delete操做..."); } }); } public void getConnection(){ System.out.println("得到链接..."); } public void releaseConnection(){ System.out.println("释放链接..."); } }