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

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. 让WPS10显示为offic97效果

    让WPS10显示为offic97效果2019/1/26 22:02 OS:win7 64位使用的WPS_10.1.0.5603_setup.1460689247.exe 衣不如旧,人不如新.最开始接触 ...

  2. c# 从DataGridVieew导出到excel

    public static bool DataGridViewToExcel(DataGridView dataGridView, bool isShowExcel) { int rowsQty = ...

  3. codevs 1043 方格取数 2000年NOIP全国联赛提高组

    时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 设有N*N的方格图(N<=10,我们将其中的某些方格中填入正整数,而 ...

  4. codevs 2905 足球晋级

    时间限制: 1 s  空间限制: 64000 KB  题目等级 : 黄金 Gold   题目描述 Description A市举行了一场足球比赛 一共有4n支队伍参加,分成n个小组(每小组4支队伍)进 ...

  5. 3.12 在运算和比较时使用NULL值

    问题:NULL值永远不会等于或不等于任何值,也包括NULL值自己,但是需要像计算真实值一样计算可为空列的返回值.例如,需要在表emp中查出所有比“WARD”提成(COMM)低的员工,提成为NULL(空 ...

  6. zabbix实现自动发现功能添加磁盘监控

    zabbix实现对磁盘动态监控 - Lenwood 原文  http://www.cnblogs.com/baizhantang/p/3253246.html 主题 Linux命令 zabbix 前言 ...

  7. PHP15 Smarty模板

    学习目标 Smarty基本概念 Smarty安装和配置 Smarty模板设计 Smarty流程控制 Smarty基本概念 一种模板引擎,在系统中进行预处理和过滤数据.是主流的PHP模板引擎,此外PHP ...

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

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

  9. Linux CentOS 知识和常用命令

    1.常用热键 [Tab]它具有“命令补全”与“文件补全”的功能[Ctrl+C]中断执行中的程序组合键[Ctrl+d]键盘输入结束.也可以用来替代 exit 2.Linux 常用编辑器 vi 和 vim ...

  10. 使用SimpleDateFormat 将毫秒转换成时分秒 格式:HH:mm:ss

    public static String dateFormatFromMilliSecond(long seconds) {        //初始化format格式    SimpleDateFor ...