《Java异步编程实战》是一本由翟陆续著作,机械工业出版社出版的平装图书,本书定价:79,页数:284,特精心从网络上整理的一些读者的读后感,希望对大家能有帮助。
《Java异步编程实战》读后感(一):我与《Java异步编程实战》的故事
我是一名程序员,过着996的生活。
但我创造了一个世界,这个世界很忙碌,每天不停地运转,在这个世界里,我是它们的造物者,掌管着所有人的生杀大权。
这个世界由多个部门组成,为了使这个世界有条不紊地运转,我费了很多功夫,还需要定时地检查运转情况,比如谁偷懒了,谁累趴了等等。
这个世界都是同步执行的,看似平静,但随着外面世界的变化,这种平静慢慢地被打破了。
首当其冲的是我们的网络驿站,主管部门是网络通信部,它负责处理外部给他的包裹,并按照包裹内的指示作出回应,最近给他投递包裹的人越来越多,线程工厂那边搬运完包裹,交给数据库管理员后,就静静地喝茶看报,等待结果,数据库满头大汗地跑来跑去,好不容易凑足了数据,刚交给线程厂的小伙子,下一个包裹又来了,马不停蹄也做不完,主子又不肯加人手,干脆不干了……
原来这个世界是虚拟的电商系统。
程序员察觉到异常,开始盘查这个世界的运作情况,他发现线程厂的小伙子们总是特别闲,成天到晚喝茶、游手好闲,便叫了线程厂厂长来训话,厂长也是一脸委屈,这不能怪我啊,我们都是在等数据库工厂那边,他们太慢啦,又不让我们干别的事,只能等啦。
程序员又把网络驿站的站长叫来,站长也是相当无奈,我们就只有那么多服务窗口啊,线程厂那边没响应数据给我们,我们就只有等啦,排队的人多了,怕引起踩践事故,后面就不让人进来了。
程序员开始陷入了沉思,这个世界的运作规则,可能要改一改了。
从线程工厂那边开始整改,因为就他最闲。
经过一番试验,给线程厂制定了新的工作规则:新招了一个叫Future的员工,线程小伙子把包裹数据给了数据库后,就可以把工作任务交给Future了,小伙子们去拿下一个包裹,由Future负责接收数据库的结果。
新的规则生效后,线程厂的小伙子们,喝茶看报的日子少了,忙的时候,额头也开始冒汗了,程序员对这个结果露出了一丝微笑。
平静的日子持续了一段时间,外面的人对这个世界更感兴趣了,交流也逐渐变多了,各部门要开始忙碌起来了,偶尔向程序员吐槽吐槽人手不够的问题,看来还需要进一步提高效率才行。
这次没上回那么紧迫,可以对所有部门好好梳理梳理。
各部门呈报上来的整改方案:
1. Controller小组反馈:外部给我们的包裹指示,有部分工作的结果是不需要响应给外部的,但我们也在等他们处理的结果,要求这部分异步化处理。
2. Servlet小组反馈:我们提供的IO是阻塞式的,没有人手处理时,会造成外部卡顿,要求改成非阻塞IO。
程序员找来《Java异步编程实战》,开始新的一轮重构...
《Java异步编程实战》读后感(二):我与异步编程的故事
在最开始学习Java的时候,就只会从上往下一把梭地写代码,代码的编写顺序跟其执行顺序保证完全的一样,直到一堂Java课上面老师提到了一个问题:计算机的CPU就跟一个个小人一样,每个小人都只能在同一时间做一件事情,这时候如果我们的代码里面都是同步地,自上而下地做一件事情,那么势必只会有一个小人在工作,其他小人就只能干瞪眼。既然计算机要搞这么多的CPU核数,肯定不会是为了好看的,如果我们能让我们的程序同时让所有的小人都进行工作,那工作效率将会大大提升。这时候我的编程世界中就多了异步的概念,最开始会写个new Thread().start()来开个新线程做事情(那个时候还一直搞不清这个Thread方法的run()方法和start()方法的区别是什么 ̄□ ̄|| ),但是后面就发现了一些问题: 两个线程的对于同一个变量的修改会有冲突问题,开了新线程之后,我主线程想获取这个新线程计算的结果该怎么办?如果我开的线程的数量远远大于我CPU核数的时候,我这些线程是如何进行工作的? 也是在后面的不断学习之中,了解了控制线程同步的方式:使用synchronized或者Lock进行加锁。了解到了并发编程之中的原子性,可见性,有序性等概念。 对于开了新线程之后,主线程想获取新线程计算的结果的问题,就引出了Future的概念,我们可以在开启新线程之后,将这个新线程的Future对象,在我们主线程做完其他的事情之后,同步阻塞地获取原先那个新线程的返回值。我在学习RPC的原理的时候,就有碰到过这个问题,在RPC传输层使用Netty在进行网络通讯的时候,因为一条Channel上面会有各种各样的请求,但是我们的每次请求都需要与其对应的返回值一一对应,这时候我们需要在发送方的数据包中新增RequestId的一个唯一Id,然后需要将其返回值封装为一个Future对象,然后服务方将这次请求处理完之后,在其对应的Response数据包中也需要添加Request请求数据包之中的那个唯一Id并返回给发起方之后,发起方根据这个唯一Id,在请求池中找到其对应的那个Future对象,并将其返回值设置到对应的Future对象之中,即完成了这次请求。 后面再深入了解NIO的时候,接触到了同步与异步,阻塞与非阻塞的概念,当时真的是一脸懵逼,感觉这些概念特别的绕,一直无法理解什么叫阻塞,什么叫非阻塞,后来在不断的了解中大概有了一些想法:同步和异步其实指的是,请求发起方对消息结果的获取是主动发起的,还是等被动通知的。而对于阻塞来说,通常指的是针对IO的操作,如网络IO和磁盘IO等。简单的来说就是我们调用了一个IO函数之后,当前线程是一直挂起直到IO操作完成,还是当前线程先去做其他事情,但是时不时去查看下当前的IO操作是否完成。
本次了解到华章图书出新书《Java异步编程实战》,因为我一直依赖对于异步编程都非常有兴趣,并且得知到本书中有关于反应式编程,以及中间件中关于异步的实现,这些也都是我非常感兴趣的部分,希望能从本书中得到相关知识的学习。最后,希望本书能够大卖!!
《Java异步编程实战》读后感(三):我与Java异步编程的小美好
当初大学义无反顾走上Java道路,就是觉得Java很有意思,记得刚工作那会,整天比较多的都是写简单的增删改查,在我动力日渐消散的时候,头儿给的很多学习文档我还没看完,头儿又说:“Java光会简单的添删改查什么的不行,要深入了解,多去看看Java高级编程,比起异步编程,高并发多线程,JUC等等。”至此,走上了异步编程的研究之路和着迷之路。
Java在Java8之前貌似还没真正实现异步编程的方法。后来Java8借鉴了很多框架的思想,可以借助JDK原生的CompletableFuture来实现异步操作,而且用Lambda表达式来写匿名内部类大大简化了代码量。当时异步编程会使用回调或者使用其他的框架(如Netty和Guava)来实现。Java 开始方法执行到结束,都是由同一个线程完成的。这种方式虽易于开发调试,但容易因为锁、IO 等原因导致线程挂起,产生线程上下文切换。随着对应用并发能力要求越来越高,频繁的线程上下文切换所带来的成本变得难以忽视。同时,线程也是相对宝贵的资源,无限制的增加线程是不可能的。
异步编程技术目的,重点并非提高并发能力,而是提高伸缩性 (Scalability)。现在的 Web 服务,应付 QPS 几百上千,甚至上万的场景并没有太大问题,但问题是如何在并发请求量突增的场景中提供稳定服务呢?如果一个应用能稳定提供 QPS 1000的服务。假如在某一个大促活动中,这个应用的 QPS 突然增加到10000怎么办?或者 QPS 没变,但这个应用所依赖的服务发生故障,或网络超时。当这些情况发生时,服务还能稳定提供吗?虽然熔断、限流等技术能够解决这种场景下服务的可用性问题,但这毕竟是一种舍车保帅的做法。是否能在流量突增时仍保证服务质量呢?答案是肯定的,那就是异步编程 + NIO。NIO 技术本身现在已经很成熟了,关键是用一种什么样的异步编程技术将 NIO 落地到系统,尤其是业务快速迭代的前台、中台系统中。
很多时候我们都希望能够最大的利用资源,比如在进行IO操作的时候尽可能的避免同步阻塞的等待,因为这会浪费CPU的资源。如果在有可读的数据的时候能够通知程序执行读操作甚至由操作系统内核帮助我们完成数据的拷贝,这再好不过了。从NIO到CompletableFuture、Lambda、Fork/Join,java一直在努力让程序尽可能变的异步甚至拥有更高的并行度,这一点一些函数式语言做的比较好,因此java也或多或少的借鉴了某些特性。
在我们的实际项目中,需要多用Java异步编程,来提高性能。需要注意并行的工作单元的切分,以及注意有没有共享变量的使用。如果有不合理的地方,大家多指正。在Java7之前,Java中对于异步编程的实现都可能比较复杂或者实现得不够优雅,而CompletableFuture的出现则提供了异步编程的强大能力,虽然API有点多但是只要稍加理解和使用还是很好应用的,通过链式调用使原本通过回调的方式变得更加优雅,代码的可阅读性和可维护性也得到一定的提高。最近一直在学习大佬的博客,最后也给大家推荐一本此大佬的书籍,跟着大佬就是进步速度快!一起努力成为更美好的自己吧!
《Java异步编程实战》读后感(四):进阶Java高级工程师 必须理解的异步编程
谈到异步编程,首先需要理解,计算机领域中的同步操作(Synchronous)和异步操作(Asynchronous)的含义
同步操作:意味着**事件同时存在,同时发生**,在操作处理期间,发起方需要一直阻塞等到完成,在此期间不能做其他事情
异步操作:意味着**事件不是同时存在**,在操作处理期间,发起方不需要一直阻塞等到完成,在此期间可以做其他事情
举个例子,产品叫我写代码,我告诉他,很好,我开始写了,他就站我身后一直盯着我,直到我写完代码,这是同步的;产品告诉我去做,但不是一直盯着我等我工作,而是去做别的事情。当我完成时,我只需要通知他,这是异步的
大部分系统开发的编程模型是基于同步的,可是当遇到了系统需要大量阻塞等待的场景,同步编程的问题就开始显现:最典型的场景是I/O,同步操作的I/O意味着线程发起I/O读写请求后,线程必须阻塞等待直到操作完成,当应用系统有大量的I/O操作,例如文件读写,网络请求收发,同步编程的系统实现并发执行这些I/O事件则每个事件,需要每个操作由独立的线程处理,需要创建大量的线程,容易导致系统性能瓶颈
针对同步编程的需要阻塞等待的问题,异步编程提供了解决方案,即在操作处理期间线程去做别的事情,操作完成后再进行通知。实现这套机制最常见的是基于观察者模式,即通知-订阅的方式,线程提前将异步操作完成后的回调处理逻辑注册保存到指定集合中,发起一个异步操作后,去处理其他业务,当操作处理完成后,只要在集合中找到回调逻辑逻辑进行执行即可
异步编程带来的优势很明显,再也不用创建大量线程处理阻塞操作,性能大大提升,但是在普通业务开发系统中,异步并没有广泛使用起来,这是什么原因?
首先,普通系统没有大量并发请求,还没有达到性能瓶颈,普通的线程阻塞等待能处理得过来;
其次,异步程序编写比较复杂,对开发者的能力有一定要求,传统的同步程序,执行A、B、C这3步操作只要3行代码函数调用,程序就会按照代码编写顺序进行同步执行;而异步是需要注册A、B、C这3步操作的后续处理回调逻辑,当操作存在顺序则需要进行嵌套,即A的回调逻辑是执行B操作,B操作的回调是执行C,一层层嵌套,最后形成嵌套地狱
最后,异步程序调试比较麻烦,新增的回调机制导致debug起来没有同步编程那么直观;
针对上面问题,业界提供了一些解决方案,例如Java的Future可用于提交任务给线程池,基于Future可以拿到异步执行结果;高性能网络框架Netty基本统治了异步网络编程领域;WebFlux对Netty的能力再进行封装,使得能用更优雅简洁的代码完成业务系统的开发,还有go语言的异军突起在容器、高并发服务器领域大放异彩
异步编程可以说是进阶Java高级工程师的必须掌握的知识,业界这块的资料比较少,最近刚好新出了淘宝资深研发写的《Java异步编程实战》,深入剖析Java、go语言异步编程能力,系统讲解各种Java开发框架、异步编程框架、中间件异步编程原理,值得学习
《Java异步编程实战》读后感(五):并发与并行 同步或异步
## 并发与并行 我们都知道,程序猿是一种逻辑性极强的生物,他们不擅言辞,不擅表达,但是他们能够用一种神秘的语言与机器进行沟通,知道怎么让机器听他们的。机器是线性思维,为了能够更高效的与机器沟通,程序猿主动或被动或潜移默化的转变思维模式,思维逐渐变得线性。最直观的表现就是,程序猿一次只能做一件事情,如果同时做多件事情,他们就会感觉不安,内心不够自信,我们戏称单线程生物。这其实是与机器微观世界有一定的契合度。 早期,机器硬件资源不足:内存不够、CPU运行效率低,只能一个一个执行程序,有人占着CPU,其他的就别着急,慢慢等着,一旦CPU被释放,各凭本事,谁抢到算谁的,当然也有通过排队方式的。 后来,发现这种方式不够公平,有的程序运行时间长,长达几分钟,有的运行时间短,可能几毫秒就完事,结果几毫秒的程序需要等待几分钟的程序执行完,于是并发就出现了。既然都想用CPU,那就限定用的时间,称之为时间片,还是抢CPU,谁抢到谁就执行,但是只能运行规定的时间,超过时间,主动让出CPU。这样大家就都能够公平运行了。 再后来,随着技术发展,CPU不再只有一个,那就多个程序一块执行。就像多条车道,每条车道上都可以行驶,这就是并行。 随着同时执行的程序逐渐增多,抢夺资源和等待资源的情况越来越多,一个程序占着CPU,但是需要等待另外一个资源。于是就这么干等着,直到拿到资源。这是严重浪费CPU资源,因为不是每个占有CPU的程序,都在100%工作。于是就有了监工,既然你得等,那到哪都是等,先休息下,等下个时间片你再来看看资源够不够,够了就执行,不都再继续等。 但是这样也不好,也浪费了检查资源的时间。那就索性睡觉,等资源好了,叫醒你,你再来抢CPU。 ## 同步或异步 机器世界的运行规则,就是程序猿代码中的规则。 比如一个下单逻辑,我们需要生成订单、锁定库存、生成支付单,支付完成后,我们需要修改订单状态、减库存、修改支付单状态、核销积分、生成待发单。。。这一系列的过程涉及N多个业务,也会涉及N多个服务(微服务嘛),如果一味等等待,势必造成很多的浪费,比如,生成订单时等锁定库存的方法程序,但是成千上万甚至上百万的商品,找到指定的商品,锁定库存信息,费时费力。 最简单的方式是,生成订单,然后生成一条消息,告诉库存服务,这个商品该锁库了,赶紧的。订单服务没有一丝的延迟,用户响应及满意度得到提升。 这是异步的场景之一,属于业务异步。 还有一种情况属于程序异步。 最典型的是Netty中的异步网络编程,一个网络请求过来,Netty不是傻乎乎的等着这个一步一步的处理,而是网络请求处理器把请求包往后一扔,告诉后面的小弟,你们自己处理哈,然后就继续等着接收其他的请求。然后小弟们把请求处理完之后,告诉前面的网络请求处理器,再把响应发送给请求者。 JDk8中也增加了很多异步编程的特性,比如CompletableFuture。 同步编程和异步编程就好比领导安排工作:有时候,他会盯着你干,知道结束,这是同步;有时候,他只是说明工作内容,你自己干,干完之后,向领导汇报。 异步编程是对资源的合理利用与编程技巧,越来越多的程序猿及公司开始重视异步编程。
《Java异步编程实战》读后感(六):异步编程分享
相信本书介绍了CompletableFuture,大家就会认识到什么是异步编程。异步编程的好处。
异步编程最大好处就是:高并发,异步处理,速度快,请求量不会一直堆积。避免流量冗余,或者服务宕机的情况。此书很好的介绍了异步编程的实战。结合实际案例来分析异步编程,并且介绍了jdk的新特性。很好的解决了大多数读者目前的现实工作或学习中的问题,是一个值得借鉴的书籍。
一般不怎么夸张,但是看到本书的目录,还是要说说,感觉比较接地气。还是比较不错的,相信也有读者看了本书,也有一定的感受吧。
正是因为CompletableFuture的出现,才使得使用Java进行异步编程提供了可能。 异步编程技术目的,重点并非提高并发能力,而是提高伸缩性 (Scalability)。高内聚,低耦合。
CompletableFuture在Java里面被用于异步编程,异步通常意味着非阻塞,可以使得我们的任务单独运行在与主线程分离的其他线程中,并且通过 回调可以在主线程中得到异步任务的执行状态,是否完成,和是否异常等信息。CompletableFuture实现了Future, CompletionStage接口,实现了Future接口就可以兼容现在有线程池框架,而CompletionStage接口才是异步编程的接口抽象,里面定义多种异步方法,通过这两者集合,从而打造出了强大的CompletableFuture类。
Futrue在Java里面,通常用来表示一个异步任务的引用,比如我们将任务提交到线程池里面,然后我们会得到一个Futrue,在Future里面有isDone方法来 判断任务是否处理结束,还有get方法可以一直阻塞直到任务结束然后获取结果,但整体来说这种方式,还是同步的,因为需要客户端不断阻塞等待或者不断轮询才能知道任务是否完成。
Future的主要缺点如下:
(1)不支持手动完成
这个意思指的是,我提交了一个任务,但是执行太慢了,我通过其他路径已经获取到了任务结果,现在没法把这个任务结果,通知到正在执行的线程,所以必须主动取消或者一直等待它执行完成。
(2)不支持进一步的非阻塞调用
这个指的是我们通过Future的get方法会一直阻塞到任务完成,但是我还想在获取任务之后,执行额外的任务,因为Future不支持回调函数,所以无法实现这个功能。
(3)不支持链式调用
这个指的是对于Future的执行结果,我们想继续传到下一个Future处理使用,从而形成一个链式的pipline调用,这在Future中是没法实现的。
(4)不支持多个Future合并
比如我们有10个Future并行执行,我们想在所有的Future运行完毕之后,执行某些函数,是没法通过Future实现的。
(5)不支持异常处理
Future的API没有任何的异常处理的api,所以在异步运行时,如果出了问题是不好定位的。
本书主要介绍了CompletableFuture的定义,概念及在Java中使用的例子,通过CompletableFuture我们可以实现异步编程的能力,从而使得我们开发的任务可以拥有更强大的能力。
值得大家看看,分享下!
《Java异步编程实战》读后感(七):2020java线程学习最系统书籍
第一次接触多线程是在学校的操作系统课程上,那时候学校的教材是郑扣根翻译的那本操作系统概念(第七版),厚厚的一本几百来页,老师上课也只是挑着来讲。后来在上java的课时,再次接触到了多线程这个概念,我想大部分人也都接触过,那个多窗口同时卖车票的经典例子吧,这是我第一次实际动手写的第一个java多线程的demo。随着课程的深入,我了解到的线程创建方式有三种,那个时候也仅仅知道三种线程的创建方式继承Thread类创建线程、实现Runnable接口创建线程和使用Callable和Future创建线程,前两者的实际线程对象都是thread对象,而后者Callable提供了一个call方法作为线程执行体,该方法可以有返回值且能声明抛出的异常,读书时还没有接触到线程池的概念,直到第一次秋招面试的时候,我才知道有线程池这个东西。而线程池的出现最大的优点就在于把任务提交和执行解耦,而我第一次接触的线程池框架就是jdk1.5引入的Executor框架,只需把Task描述清楚,然后提交即可。这个Task是怎么被执行的,被谁执行的,什么时候执行的,提交的人就不用关心了。具体点讲,就是提交一个Callable对象给ExecutorService(如最常用的线程池ThreadPoolExecutor),将得到一个Future对象,调用Future对象的get方法等待执行结果就好了。Executor框架的内部使用了线程池机制,它在java.util.cocurrent 包下,通过该框架来控制线程的启动、执行和关闭,可以简化并发编程的操作。因此,在Java 5之后,通过Executor来启动线程比使用Thread的start方法更好,除了更易管理,效率更好(用线程池实现,节约开销)外,还有关键的一点:有助于避免this逃逸问题——如果我们在构造器中启动一个线程,因为另一个任务可能会在构造器结束之前开始执行,此时可能会访问到初始化了一半的对象用Executor在构造器中。
后来又陆续接触到了五种线程池newCachedThreadPool、newWorkStealingPool、newSingleThreadExecutor、newFixedThreadPool、newScheduledThreadPool,这些线程池都有各自应用场景, newCachedThreadPool适合服务器负载较低且很多短期异步任务需要执行,newFixedThreadPool适合服务器负载较重,对当前线程数量进行限制,newSingleThreadExecutor适合单线程顺序执行各个任务,newScheduledThreadPool适合延时,定时启动多个任务,newWorkStealingPool适合多任务队列,需并行操作的任务。
上个月我正在做的一个关于房产的项目,其中涉及到楼盘筛选,因为楼盘的一些指标需要根据楼盘去统计房间相关数据,而房间数据又过于庞大导致查询性能低下,尝试了多种方式,用mongodb、内存表、es,发现最终只有es可行,但是采用es存储必然意味着架构需要重新调整,而上线在即,并没有这么多时间让我们立即改用es这个方案,我们唯有继续思考,朝数据量大这个点突破,因为房间和楼盘相关,如果我们将楼盘分组,并发执行sql是否就可以撑一版,这么一想我就用ThreadPoolExecutor建了核心和最大线程为30的单个线程池,然后用Future对象将这些分组的楼盘分别提交,最后使用Future的get方法拿到异步返回的所有结果,将数据聚合,再进行相关操作,最终使得该查询功能得到质的提升。虽然,最终该功能没有上线,但是也为类似的一个因性能所困的业务提供了一个解决问题的方案,最终,版本如期上线。
《Java异步编程实战》读后感(八):JVM从并发到异步
这两天正在看《Java并发编程实战》呢,昨天就看到机械工业出版社要出版《Java异步编程实战》了
从上大学的时候开始接触多线程编程,然后当时就在听业界的人说异步编程。
工作了之后,发现异步编程的执行效率是高,但代码写起来很容易陷入回调地狱,大家还是用同步的写法。
然后业界就开始探索如何写的更好点。
最简单的方式其实就是直接并发,多开几个线程执行,如果要操作共享数据则加锁,然后最后利用同步原语等待结束就行。
后来大家发现线程创建很耗时,所以就用了线程池,但立马就遇到一个问题,线程的任务处理很复杂,比如等待队列大小、超时,队列满了的处理等等。(我们就遇到过线上线程池满了导致死锁的问题)
还有一个问题就是线程同步,CAS操作、指令重排、重入锁、乐观锁、悲观锁、公平锁、非公平锁、独占锁、共享锁等等,都需要在写多线程代码的时候异常小心。
但是更加麻烦的地方其实在线上问题排查,比如线程池出了异常,只能看到线程池内部的stacktrace,根本不明白任务是从哪儿提交到线程池的,所以这个stacktrace是“不完整的”,没法追踪到调用的开始。
当然,最严重的问题其实是线程的调度是一个很大的开销,尤其是在QPS很大的时候。
所以就开始异步编程探索
异步编程极大的提升了CPU的利用率,同步是CPU在等IO,并发是CPU在调度,异步则让CPU大部分时间在处理业务逻辑。
但这个解决方案并不是完美的,netty作为典型的异步回调式编程模型,它很多时候都是用回调。遇到IO,搞一个回调,遇到CPU密集的任务,放到线程池。
但是回调和线程池都会丢失上下文,即任务失败的日志里面,是看不出来谁触发了这个任务的。
比如一个异步调用获取用户信息的任务,如果出错了,从stackstrace里面是看不出来哪个页面出了问题的。
然后看了下,Python和node的协程(async/await)很好的解决了这个问题,写代码的时候按照同步的写,在有些点加上await就可以异步调用了,也不用回调,stacktrace也能看到全部的上下文。
但,在编码的时候,还是得关注函数是不是异步的,什么时候该加await,什么时候不加。这对程序员来说,也是一个很大的负担。
这时,golang采用了stackfule的协程。
你只管同步写,也不用写什么async/await。调度的事情是框架/运行时负责,程序员写起来也方便、也能够利用异步的优势。
那么jvm呢?project loom就是一个非常好的尝试,将协程藏在Thread后面,业务代码无感知,执行的时候还是异步。
但是问题在于,这么长时间了,还只有一个 Early-Access Build,它的路还很长……
另外一个值得关注的项目就是AJDK中的wisp2,看起来也是实现了stackful的协程,据说明年开源,期待!
在loom可用之前,还是得看看这本《Java异步编程实战》,用异步的方式思考和编码。
《Java异步编程实战》读后感(九):推荐推荐推荐,重要的事情说三遍
这个世界的运转就是异步的,因此异步编程变得越来越重要。我们在最开始学习编程的时候都是编写同步的代码,随着学习的深入,为了提高系统性能,就会使用异步编程来处理一些任务,从而提高系统的吞吐率。但是异步编程会产生一些新的问题,比如如何监控异步线程的状态,如何处理错误,如何管理大量的线程,这些问题都使我意识到必须要深入地学习异步编程。
异步编程可以很好的平衡IO密集型任务和CPU密集型任务之间的分工合作。充分利用计算机CPU资源,不让CPU阻塞在某个长时间运行的任务上,提高CPU运行的吞吐率。如果不使用多线程异步编程,我们的系统就会阻塞在耗时的任务上,十分浪费计算资源。Java 语言对异步编程提供了良好的支持。特别是在Java 8中,对异步编程进行了很大的改进。Java 8 可以算是 Java 中一个里程碑版本,添加许多让人惊叹的新的特性,其提供了丰富的API,来完成多线程异步编程,例如NIO、Future、CompletableFuture、Fork/Join以及parrallelStream。除此之外guava和Spring等框架都提供了相关支持来简化异步编程。
我最开始接触异步编程是在学习Netty的时候,Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。慢慢地我对异步编程有了一些了解,也开始慢慢深入学习,对于异步编程,使用起来大大地提高了效率,也在学习过程中收获了许多。但是由于缺乏这方面的资料,在学习过程中也踩了很多坑,急切需要一本异步编程的书籍来为自己的学习指引方向。
虽然Java为不同技术域提供了相应的异步编程技术,但是这些异步编程技术被散落到不同技术域的技术文档中,没有一个统一的文档对其进行梳理归纳。另外这些技术之间是什么关系,各自的出现都是为了解决什么问题,我们也很难找到相关资料来解释。学习异步编程也就成了程序员面临的一大挑战,要想写出优秀的异步编程代码,既需要对异步编程的原理有深刻的理解,也需要对各种异步编程框架有熟练的掌握,没有一本专业的书籍领路,可谓是异常的艰难。好在加多老师出了《Java异步编程实战》这本书,深入剖析了Java、go语言编程,相信通过阅读此书,可以让你对异步编程的理解更上一层楼。
《Java异步编程实战》针对各种常见异步编程场景,从编程语言、开发框架等角度深入讲解了异步编程的原理和方法。作者是资深Java技术工程师,就职于淘宝,有多年的Java研发经验,在Java并发编程、异步编程等方面有深入研究和积累。对JUC包源码有深入的理解,熟悉常用开源框架实现原理。并著有畅销书《Java并发编程之美》。整本书由浅入深,是一部全面解析Java异步编程的著作,针对各种常见异步编程场景,从编程语言、开发框架等角度深入讲解了异步编程的原理和方法。本书首先介绍了异步编程的概念、适用场景,以及如何使用线程和线程池来实现异步编程;再讲解JDK中的各种Future及其内部实现原理,然后讲解如何使用Future实现异步编程,以及如何结合JDK8 Stream 和Future实现异步编程;以及对Spring框架中提供的异步执行能力进行详细分析,包含Spring中如何对TaskExecutor进行抽象,如何使用注解@Async实现异步编程,以及其内部实现原理;最后讲解了最近比较热门的反应式编程相关的内容,包含什么是反应式编程,如何使用反应式编程规范的库RxJava和Reactor库实现异步编程。全书注重理论与实践相结合,且每个异步技术点都附有代码实例,帮助读者加深理解。早买早享受,赶快点击下面的链接买起来吧。
购买链接:https://item.jd.com/12778422.html
《Java异步编程实战》读后感(十):Java异步编程思考
作为一门诞生了20多年的编程语言,JAVA以出色的功能特性在企业应用中占据核心地位,广泛应用与后端开发、手机应用开发、大数据等众多领域,虽然在起初的架构设计上存在各种各样的缺陷以及受到后来者的疯狂挑战,然而,经过每一次次的版本迭代、功能优化、新特性引入,使得Java在实际的企业业务场景中仍处于较高的地位。尤其是Java异步编程技术的发展,可谓推动了Java技术的革命性进步。
做过Java开发的小伙伴们都知道,Java语言编程其方法开始执行直至其结束,均是由同一个线程去处理完成的。此种模式虽然便于我们开发调试,但会因种种原因导致线程挂起,比如:锁、IO 等资源,从而会产生线程上下文切换,耗费较多资源。毕竟,作为操作系统里面的一个调度单元,线程是一个很宝贵的资源,无限制的增加线程通常情况下是不可取的,况且基本上也是不可能实现的的,因为资源是有限的。因此,我们应该能够让我们应用占用较少的线程资源实现更高、更优的并发处理能力,这才是我们所追求的,为此,我们在实际的项目中需引入新的技术 ,即“Java 异步编程技术”
在实际的项目中,异步编程技术是不可缺少的技能,异步编程可分为以下两种:Java虚拟机内部的异步编程和Java虚拟机之间的异步编程。从本质上来说,异步编程是一种编程方式,可以提高对UI的快速响应。 异步编程提供了一个非阻塞的,事件驱动的编程模型。Java中的异步编程模型提供了一致性的编程模型, 可以用来在程序中支持异步。
其实,从系统架构层面来讲,异步编程技术实现目的,并非是提高并发能力,而是重点在于提高其“伸缩性 (Scalability)”。当前所流行的微服务架构, 无论是基于Apache Dubbo还是Spring Cloud体系,支撑成千上万的应用场景应该没有太大问题,如何使得并发请求业务量在突飞猛进的场景中提供高效、稳定的服务才是关键所在。举个现实中的场景:某商户应用系统,其中一个核心应用在正常的情况下能够对外稳定提供服务其处理能力为800,在某一次的大型促销活动中,这个应用的 TPS 在某一时间段内瞬间增加到10000,这种场景情况下,该如何处理呢?当然还有一种场景,TPS未发生变化,由于高流量的导入使得此核心应用所依赖的服务发生故障,或TimeOut Exception。当这些现象出现时,应用系统还能够持续稳定提供服务吗?当然,我们可以借助熔断、限流等技术来规避、解决这种场景下服务的可用性问题,但这毕竟是一种舍车保帅的做法。是否在流量突增场景下仍能够持续保证服务质量呢?那就是借助异步编程 + NIO去实现。NIO 技术本身现在已经很成熟了,关键是用一种什么样的异步编程技术将 NIO 快速、高效地落地到应用系统当中。
Java异步编程从前期的Future技术到现在的Project Loom,可谓“一路艰辛”,中间历经:Callback、Servlet3.0、反应式编程、Kotlin 协程。与之前所提及的Java异步编程方案相对比,Project Loom 是从 JVM 层面对多线程技术进行彻底的改变。长期以来,Java 的线程是与操作系统的线程一一对应的,这限制了 Java 平台并发能力的提升。各种框架或其它 JVM 编程语言的解决方案,都在使用场景上有限制。例如 Kotlin 协程必须基于各种 Callback 技术,而 Callback 技术有存在编写、调试困难的问题。为了使 Java 并发能力在更大范围上得到提升,从底层进行改进便是必然。当然,在每一特定阶段每一种技术都有各自的优势与缺陷,在实际的项目中应合理选取。
异步编程对于设计大规模、快速响应的应用架构是至关重要的。借助异步回调方法来执行昂贵的I/O操作从而、而使得处理器可以执行其它任务。当前所流行的语言中,Node与Go几乎天生支持异步编程模式,Java虽然提供了异步的支持,但是异步编程并不总是那么容易实现,不过,不要紧,最新出版的国内首本异步编程著作《Java异步编程实战》将会为您揭晓其中的奥秘!