在正常的业务中使用同步线程,若是服务器每处理一个请求,就建立一个线程的话,会对服务器的资源形成浪费。由于这些线程可能会浪费时间在等待网络传输,等待数据库链接等其余事情上,真正处理业务逻辑的时间很短很短,可是其余线程在线程池满了以后又会阻塞,等待前面的线程处理完成。并且,会出现一个奇怪的现象,客户端的请求被阻塞,可是cpu的资源使用却很低,大部分线程都浪费在处理其余事情上了。因此,这就致使服务器并发量不高。数据库
而异步,则能够解决这个问题。服务器
咱们能够把须要用到cpu的业务处理使用异步来实现,这样其余请求就不会被阻塞,并且cpu会保持比较高的使用率。网络
今天就学习了使用回调来实现异步的方法。咱们设想一个情景,A是处理业务的一个步骤,A须要解决一个问题,这时候A能够问B,让B来告诉A答案,这期间,A能够继续作本身的事情,而不用由于B作的事而阻塞。因而,咱们想到给B设置一个线程,让B去处理耗时的操做,而后处理完以后把结果告诉A。因此这个问题的要点就在于B处理完以后如何把结果告诉A。咱们能够直接在A中写一个方法对B处理完的结果进行处理,而后B处理完以后调用A这个方法。这样A调用B去处理过程,B调用A的C方法去处理结果就叫作回调。并发
1 package CallBack; 2 3 public interface CallBack { 4 /* 5 *A处理结果的方法,为何要写这个接口呢? 6 *由于可能不止A须要用到B的处理过程,若是不少地方须要用到B 7 * 那么传入B的方法就不可能只传A类,因此要定义一个接口, 8 * 传入B的处理方法的参数就是这个接口对象 9 * */ 10 public void solve(String result); 11 }
1 package CallBack; 2 3 public class A implements CallBack { 4 private B b; 5 6 public A(B b){ 7 this.b=b; 8 } 9 10 //A须要解决一个问题,因此他把问题交给B处理,B单首创建一个线程,不影响A的运行 11 public void ask(final String question){ 12 System.out.println("A问了B一个问题"); 13 new Thread(()->{ 14 //B想要帮A处理东西,就必须知道谁让本身处理的,因此要传入a,也要知道a想处理什么,因此要传入question 15 b.executeMessage(A.this,question); 16 }).start(); 17 //A把要处理的事情交给b以后,就能够本身去玩耍了,或者去处理其余事情 18 play(); 19 } 20 21 public void play(){ 22 System.out.println("我要逛街去了"); 23 } 24 25 //A拿到了B处理完成的结果,能够进行一些操做,好比把结果输出 26 @Override 27 public void solve(String result) { 28 System.out.println("B告诉A的答案是--》"+result); 29 } 30 31 }
1 package CallBack; 2 3 public class B { 4 public void executeMessage(CallBack callBack,String question){ 5 System.out.println(callBack.getClass()+"问的问题--》"+question); 6 try { 7 Thread.sleep(3000); 8 } catch (InterruptedException e) { 9 e.printStackTrace(); 10 } 11 String result="答案是2"; 12 callBack.solve(result); 13 } 14 }
1 package CallBack; 2 3 public class test { 4 public static void main(String[] args) { 5 B b=new B(); 6 A a=new A(b); 7 a.ask("1+1=?"); 8 } 9 }
运行结果: A问了B一个问题 我要逛街去了 class CallBack.A问的问题--》1+1=? B告诉A的答案是--》答案是2 Process finished with exit code 0