认识异步、非阻塞、futrue、callback

11 篇文章 0 订阅

高并发、大访问量实际是程序猿界的分水岭,如何从各个角度去解决这些问题?这也是面试的时候架构师被问过的最多的问题。而异步、非阻塞对于性能的提升是每个武林高手的锦囊妙计。

异步和非阻塞是什么关系?什么区别?

此问题一出,可以直接鉴别真伪,不信你问下试试~哈哈!!!看完此文,相信你就清楚了。

异步毫无疑问,就是启动多个线程,让每个线程去做一部分工作,互不干扰。

当需要汇聚结果的时候,必须采用futrue的模式。简单来讲,就是当你用多线程异步的去执行的时候,如果不需要知道结果,可以直接结束。但是当你需要知道结果的时候,最好采用callablefutrue配合完成。例如,如果对用户表进行了水平切分,需要从多个表查询数据时,就可以采用这种方式。Futrue就是你需要得到的结果。它代表的是未来,因为是异步,future.get()不一定有结果,如果你去get的时候还没有结果,是会被阻塞的。但是在你必须获取结果之前,还可以做很多事情,这时候是不受影响的。是非阻塞的状态。

Future模式需要通过轮训或阻塞等待的方式,才能得到结果。这样总是显得不太优雅,比较好的方式应该是callback(回调函数,写过ajax的肯定比较清楚)的方式,也就是执行结束的时候异步通知完成状态。然后再去futrue中取执行结果。

实际上futruecallback这种经典的模型在很多语言里都有了原生的支持,jdk中虽然有futrue,但是并不支持callback模式。还好guava给我们又打开了一扇窗——ListenableFuture在jdk8中已经得到了完善。找个时间再写写。

异步、非阻塞给你带来的问题就是调试的麻烦,编程复杂度的提升,不过有了这些工具类,变得简单了很多。如果公司有开发框架的话,可以直接封装在底层。

直接上代码,可以仔细看下注释,你就明白整个过程了。

public class FutureExample {
   public static void main(String[] args) throws Exception {
       // jdk自带Future模式,实现异步,交给线程池处理任务
      ExecutorService jdkExecutor =Executors.newSingleThreadExecutor();
       Future<String> jdkFuture = jdkExecutor
               .submit(new Callable<String>() {
                   @Override
                   public String call() throws Exception {
                      // 模拟业务消耗时间

                   TimeUnit.SECONDS.sleep(100);
                      return "This is native future call.not supportasync callback";
                   }
              });
       // Future只实现了异步,而没有实现回调.所以此时主线程get结果时阻塞.或者可以轮训以便获取异步调用是否完成,提交到线程池到get结果之间是非阻塞的,可以处理其他任务。
      System.out.println(jdkFuture.get());
       // 好的实现应该是提供回调,即异步调用完成后,可以直接回调.本例采用guava提供的异步回调接口,方便很多.
      ListeningExecutorService guavaExecutor = MoreExecutors
              .listeningDecorator(Executors.newSingleThreadExecutor());
       final ListenableFuture<String>listenableFuture = guavaExecutor
               .submit(new Callable<String>() {
                   @Override
                   public String call() throws Exception {
                      Thread.sleep(1000);
                      return "this is guava future call.support asynccallback";
                   }
              });
       // 注册监听器,即异步调用完成时会在指定的线程池中执行注册的监听器
      listenableFuture.addListener(new Runnable() {
           @Override
           public void run() {
               try {
                                             System.out.println("async complete.result:"+ listenableFuture.get());
                                          } catch (Exception e) {
               }
          }
      }, Executors.newSingleThreadExecutor());
       // 主线程可以继续执行,异步完成后会执行注册的监听器任务.
      System.out.println("go on execute.asyn complete willcallback");
       // 除了ListenableFuture,guava还提供了FutureCallback接口,相对来说更加方便一些.
      ListeningExecutorService guavaExecutor2 = MoreExecutors
              .listeningDecorator(Executors.newSingleThreadExecutor());
       final ListenableFuture<String>listenableFuture2 = guavaExecutor2
               .submit(new Callable<String>() {
                   @Override
                   public String call() throws Exception {
                      Thread.sleep(1000);
                      System.out.println("asyncThreadName:"
                              + Thread.currentThread().getName());
                      return "this is guava future call.support asynccallback using FutureCallback";
                   }
              });
       // 注意这里没用指定执行回调的线程池,从输出可以看出,默认是和执行异步操作的线程是同一个.当然也可以再起一个线程池,取决于处理的复杂度,和相互之间的影响。
      Futures.addCallback(listenableFuture2, new FutureCallback<String>() {
           @Override
           public void onSuccess(String result) {
               System.out
                      .println("async callback(using FutureCallback) result:"
                              + result);
              System.out.println("execute callback threadName:"
                      + Thre           }ad.currentThread().getName());
           @Override
           public void onFailure(Throwable t) {
           }
       });
 }
}



参考文献:

http://www.blogjava.net/landon/archive/2014/02/27/410387.html(代码)

http://ifeve.com/google-guava-listenablefuture/


更多文章欢迎关注我的微信公众号,奔跑中的蜗牛,可以扫描头像关注


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值