在看下文之前,先给大家科普一点基础知识

Runable:线程任务类接口,没有返回值

Callable:与上面的不同就是有返回值

Executor:定义了线程池执行任务的接口,不过只定义了Runable的,也就是execute

ExecutorService:是线程池的规范,像ThreadPoolExecutor就是它的实现类,继承了Executor,并且自己还扩展了对于Callable任务类的执行规范,也就是submit()

Executors:一个工具类,提供了一些有默认配置的线程池,如new FixedThreadPool(int num),其实除了newWorkStealingPool(使用的是ForkJoinPool)外使用的都是ThreadPoolExecutor,包括ScheduledThreadPoolExecutor,定时器线程池,只是队列使用的是
DelayedWorkQueue这种延时阻塞队列.

Future: java对于future模式实现的接口
FutureTask:Future接口的实现类

首先,请大家思考一个问题,异步与同步是什么?区别在哪里?看清楚,这里说的是异步和同步,而不是阻塞与非阻塞(阻塞与非阻塞的区别是在于线程是否被阻塞的概念,也就是碰到一个会阻塞的代码(如IO)你是开启子线程去运行让主线程直接过还是让主线程去阻塞等着).

相比于阻塞和非阻塞这种定义非常清晰直观的观念,同步与异步的概念则非常模糊,在我刚接触NIO与AIO的时候因为网上各种博客的误导以及自己也没有花时间思考其本质(独立思考很重要,不要只是被动接受),导致一度理解为同步和异步的概念是操作系统级别的,也就是这个任务的触发是系统主动通知你(回调)的,还是你在程序里不停的轮询查看是否达到触发条件的.

其实,这只是表面现象,大家想想,程序主动访问和系统通知你,这两个真正的区别在于什么?其实是在于一个是需要我们不停的轮询,不停的人为查看.而另一个则是通过回调函数,也就是由完成任务的事件触发的,不需要我们去人为观察的.这才是同步和异步的区别,同步在某一个点上仍然需要去主动访问我们的任务线程.而异步,则是任务线程自己告诉我们,我们已经完成了.也就是说,它们真正的区别在于,有没有完成任务后的回调函数!

理解到了这个,我们再来说说对于CompletableFuture,首先,此类是java第一个真正的异步编程实现,FutureTask则是同步,原因也很简单,你需要主动去拿FutureTask里的返回值(get()方法),也就顺应了我们上文对于同步的观点,同步是需要我们程序去主动访问我们的任务线程

CompletableFuture则不需要我们主动获取,原因也很简单,CompletableFuture是基于事件驱动的数据处理.也就是说,CompletableFuture可以注册监听器,这样一旦我们的数据处理完成就会自动触发回调

下面是一个小的demo

从打印的信息来分析

1.在我们没有指定线程池的情况下CompletableFuture默认使用的是ForkjoinPool,而ForkjoinPoll的线程则是守护线程,这也就是我为什么要在最后join的原因.(守护线程的生存周期是依赖于前台线程的,也就是说,我主线程运行完了jvm就直接退出而不会管守护线程是否还在执行.)

2.虽然在链式的每一个调用里都指定了异步,整个方法链依然使用的是同一个线程,原因是这些调用都存在依赖关系,所以我一直觉得CompletetableFuture的链式调用挺鸡肋的.但是!虽然在链式调用里方法的运行是串行的,但对于外面调用它的线程来说,它依然是异步的(参考上文对与异步的定义)

上面之所以说CompletableFuture的概念,是因为CompletableFuture其实就是典型的响应式编程风格,为我们下面要说的WebFlux做个铺垫,所以我们下面再来说说WebFlux最大的误区,也就是响应式编程相比于Servlet效率更高,性能更好,响应时间更短

大家都知道,Spring5推出了一个WebFlux开发框架,(使用Netty做的默认服务器,并且不使用Servlet规范),利用Mono(对应单例)和WebFlux(对应多例)

我们看下面这个例子

首先请注意,Mono是Netty提供的实现而非Spring,之后再请大家思考一个过程,当我访问这个代码的时候,会发生什么呢?

Spring会去启动一个线程去处理Mono方法调用链,之后马上返回,看清楚,是启动,都不一定开始运行,可能只是就绪的状态就会返回(这里科普下线程生命周期的一个基础知识,当你启动一个线程后,此线程并非会马上运行,它还需要等待cpu的时间片)

但是!这里马上会返回的意思是处理Request请求的线程马上返回,而Response线程则不会马上响应给客户端,因为Mono线程还需要处理数据呢,而当Mono线程处理数据之后,会通过事件的形式被Response监听到,此时Response拿到数据后返回(此处可以理解为Mono在处理完数据后push给了Response)

Ok,这里大家应该都懂了吧,WebFlux框架在我们程序看来是异步的,但是在客户端响应看来还是同步的(因为我还是需要你返回给我数据我才可以响应给客户端),

也正因此,在WebFlux和传统Servlet开发都可以使用多线程的情况下WebFlux框架完全没有比之前Request和Response同步处理快的点,甚至可能会更慢,因为在开启了大量线程的情况下,线程上下文切换是一个很大的开销.要知道,WebFlux开发始终比传统开发要多开一个线程.

而且最搞笑的一点是,Spring WebFlux框架的这种做法和Servlet 3(异步处理任务,Request即时返回)殊途同归.所以WebFlux框架比Servlet效率更高,响应更快这种说法不攻自破。

所以结论就是,webflux框架真的只是一种编程风格框架,就跟java8提供的函数式编程框架Stream一样,只能降低而不能提高任何性能,webflux框架能实现的,用其它方式一样能做到。

同步OR异步?WebFlux开发真的比Servlet开发要快?顺便再科普下CompletableFuture的更多相关文章

  1. 初学 Java Web 开发,从 Servlet 开发

    1. 基本要求:Java 编程基础 有良好的 Java 语言编程基础,这是必须的,在讨论 Web 开发技术时提了一个 Java 编程基础的问题会被鄙视的. 2. 环境准备 (Eclipse + Tom ...

  2. day05 Servlet 开发和 ServletConfig 与 ServletContext 对象

    day05 Servlet 开发和 ServletConfig 与 ServletContext 对象 1. Servlet 开发入门 - hello world 2. Servlet 的调用过程和生 ...

  3. Java Servlet开发的轻量级MVC框架最佳实践

    在Servlet开发的工程实践中,为了减少过多的业务Servlet编写,会采用构建公共Servlet的方式,通过反射来搭建轻量级的MVC框架,从而加快应用开发. 关于Servlet开发的基础知识,请看 ...

  4. python 37 同步、异步调用

    目录 1. 阻塞与非阻塞 2. 同步与异步 2.1 异步调用 2.2 同步调用 2.3 异步调用回收的第一种方式 3. 异步调用+回调函数 3.1 requests模块 3.2 异步调用回收的第二种方 ...

  5. Java的同步和异步

    同步:发送一个请求,等待返回,然后再发送下一个请求 异步:发送一个请求,不等待返回,随时可以再发送下一个请求 同步可以避免出现死锁,读脏数据的发生,一般共享某一资源的时候用,如果每个人都有修改权限,同 ...

  6. Nodejs同步和异步编程

    同步API:只有当前API执行完成后,才能继续执行下一个API:异步API:当前API的执行不会阻塞后续代码的执行. 同步异步代码执行顺序 同步:从上到下依次执行,前面代码会阻塞后面代码的执行.异步: ...

  7. 浅谈Excel开发:一 Excel 开发概述

        做Office相关的开发工作快一年多了,在这一年多里,在插件的开发中遇到了各种各样的问题和困难,还好同事们都很厉害,在和他们的交流讨论中学到了很多的知识.目前Office相关的开发资料是比较少 ...

  8. 【转载】浅谈Excel开发:一 Excel 开发概述

    博客园就是好,想要什么都给总结了,多谢 原文转载:http://www.cnblogs.com/yangecnu/p/Excel-Develpment-Introduction.html 做Offic ...

  9. 关于Web开发里并发、同步、异步以及事件驱动编程的相关技术

    一.开篇语 我的上篇文章<关于如何提供Web服务端并发效率的异步编程技术>又成为了博客园里“编辑推荐”的文章,这是对我写博客很大的鼓励,也许是被推荐的原因很多童鞋在这篇文章里发表了评论,有 ...

随机推荐

  1. 开始bootstrap的学习

    终于过完双十一,服务器顶住了压力,不知道为啥,突然的轻松,反而感觉有点无所适从,好久没写博客了,竟然发现还有人回我,很是开心,问题都是关于阿里云的,阿里云的吭确实多,其实关键在于,官方文档还是少,出了 ...

  2. 在WIN7下解决coursera视频无法播放问题

    https://blog.csdn.net/u012509485/article/details/78459584在WIN7下解决coursera视频无法播放问题2019/1/20 23:18 最近C ...

  3. HTTPS时代已来,你做好准备了吗?

    早在今年年初,Google在其安全博客上已经表明,从7月开始,Chrome68会将所有的HTTP网站标记为不安全.随后,Mozilla也表明,Firefox浏览器也准备将所有HTTP网站标记为不安全. ...

  4. iOS9 开发新特性 Spotlight使用

    1.Spotloight是什么? Spotlight在iOS9上做了一些新的改进, 也就是开放了一些新的API, 通过Core Spotlight Framework你可以在你的app中集成Spotl ...

  5. ubuntu下php安装目录说明

    php当前安装目录 /etc/php5/ apache2:   采用APACHE2HANDLER启动 cli:   采用命令启动 fpm php-fpm启动 fpm2     php-fpm多实例 m ...

  6. 第一次提交代码到github时经常遇到的问题

    最近两年在OpenStack方面做了一些工作,写了一些实验性的plugin. 本着Open Source的共享精神,想尝试提交到github,以便他人能下载使用. 当你注册完github帐号之后,点击 ...

  7. EOS Dapp体验报告

    EOS Dapp体验报告 EOS通过并行链和DPOS的方式解决了延迟和数据吞吐量的难题. EOS能够实现每秒百万级的处理量,而目前比特币是每秒7笔,以太坊是30-40笔,EOS的这一超强能力吊打比特币 ...

  8. 细说PHP-5.3.4变量的引用赋值

    变量总是传值赋值.也就是说,当讲一个表达式的值赋予一个变量时,整个原始表达式的值被赋值到目标变量.这意味着,当一个变量的值赋予另个一变量时,改变其中一个变量的值,将不会影响到另一个变量.PHP中提供了 ...

  9. Dubbo框架的说明

    说实话,自己现在做的项目中有用到dubbo,但是我所负责的那一个模块,并没有涉及到dubbo,想学习一下dubbo,之前是没有学习完,这次继续... 一.背景知识总结 二.服务治理 三.Dubbo架构 ...

  10. SQL Server 2008 阻止保存要求重新创建表的更改

    取消[阻止保存要求重新创建表的更改]复选框