File tree Expand file tree Collapse file tree 5 files changed +34
-5
lines changed
high-performance/message-queue
system-design/framework/spring Expand file tree Collapse file tree 5 files changed +34
-5
lines changed Original file line number Diff line number Diff line change 1919
2020我们可以把消息队列看作是一个存放消息的容器,当我们需要使用消息的时候,直接从容器中取出消息供自己使用即可。由于队列 Queue 是一种先进先出的数据结构,所以消费消息时也是按照顺序来消费的。
2121
22- ![ Message queue ] ( https://oss.javaguide.cn/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97 /message-queue-small.png )
22+ ![ ] ( https://oss.javaguide.cn/github/javaguide/high-performance/message-queue /message-queue-small.png )
2323
2424参与消息传递的双方称为 ** 生产者** 和 ** 消费者** ,生产者负责发送消息,消费者负责处理消息。
2525
Original file line number Diff line number Diff line change @@ -142,7 +142,7 @@ icon: jianli
142142
143143项目介绍尽量压缩在两行之内,不需要介绍太多,但也不要随便几个字就介绍完了。
144144
145-
145+ 另外,个人收获和项目成果都是可选的,如果选择写的话,也不要花费太多篇幅,记住你的重点是介绍工作内容/个人职责。
146146
147147** 2、技术架构直接写技术名词就行,不要再介绍技术是干嘛的了,没意义,属于无效介绍。**
148148
Original file line number Diff line number Diff line change @@ -700,15 +700,15 @@ CompletableFuture.runAsync(() -> {
700700
701701### 合理组合多个异步任务
702702
703- 正确使用 `thenCompose()` 、 `thenCombine()` 、`` acceptEither()`、`allOf()`、`anyOf() `等方法来组合多个异步任务,以满足实际业务的需求,提高程序执行效率。
703+ 正确使用 `thenCompose()` 、 `thenCombine()` 、`acceptEither()`、`allOf()`、`anyOf() `等方法来组合多个异步任务,以满足实际业务的需求,提高程序执行效率。
704704
705705实际使用中,我们还可以利用或者参考现成的异步任务编排框架,比如京东的 [asyncTool](https: // gitee.com/jd-platform-opensource/asyncTool) 。
706706
707707! [asyncTool README 文档](https: // oss.javaguide.cn/github/javaguide/java/concurrent/asyncTool-readme.png)
708708
709709## 后记
710710
711- 这篇文章只是简单介绍了 `CompletableFuture ` 比较常用的一些 API 。如果想要深入学习的话,还可以多找一些书籍和博客看,比如下面几篇文章就挺不错:
711+ 这篇文章只是简单介绍了 `CompletableFuture ` 的核心概念和比较常用的一些 API 。如果想要深入学习的话,还可以多找一些书籍和博客看,比如下面几篇文章就挺不错:
712712
713713- [CompletableFuture 原理与实践- 外卖商家端 API 的异步化 - 美团技术团队](https: // tech.meituan.com/2022/05/12/principles-and-practices-of-completablefuture.html):这篇文章详细介绍了 `CompletableFuture` 在实际项目中的运用。参考这篇文章,可以对项目中类似的场景进行优化,也算是一个小亮点了。这种性能优化方式比较简单且效果还不错!
714714- [读 RocketMQ 源码,学习并发编程三大神器 - 勇哥 java 实战分享](https: // mp.weixin.qq.com/s/32Ak-WFLynQfpn0Cg0N-0A):这篇文章介绍了 RocketMQ 对`CompletableFuture`的应用。具体来说,从 RocketMQ 4.7 开始,RocketMQ 引入了 `CompletableFuture`来实现异步消息处理 。
Original file line number Diff line number Diff line change @@ -484,6 +484,35 @@ CPU 密集型简单理解就是利用 CPU 计算能力的任务比如你在内
484484- ** [ Hippo4j] ( https://github.com/opengoofy/hippo4j ) ** :异步线程池框架,支持线程池动态变更&监控&报警,无需修改代码轻松引入。支持多种使用模式,轻松引入,致力于提高系统运行保障能力。
485485- ** [ Dynamic TP] ( https://github.com/dromara/dynamic-tp ) ** :轻量级动态线程池,内置监控告警功能,集成三方中间件线程池管理,基于主流配置中心(已支持 Nacos、Apollo,Zookeeper、Consul、Etcd,可通过 SPI 自定义实现)。
486486
487+ ### 如何设计一个能够根据任务的优先级来执行的线程池?
488+
489+ 这是一个常见的面试问题,本质其实还是在考察求职者对于线程池以及阻塞队列的掌握。
490+
491+ 我们上面也提到了,不同的线程池会选用不同的阻塞队列作为任务队列,比如` FixedThreadPool ` 使用的是` LinkedBlockingQueue ` (无界队列),由于队列永远不会被放满,因此` FixedThreadPool ` 最多只能创建核心线程数的线程。
492+
493+ 假如我们需要实现一个优先级任务线程池的话,那可以考虑使用 ` PriorityBlockingQueue ` (优先级阻塞队列)作为任务队列(` ThreadPoolExecutor ` 的构造函数有一个 ` workQueue ` 参数可以传入任务队列)。
494+
495+ ![ ThreadPoolExecutor构造函数] ( https://oss.javaguide.cn/github/javaguide/java/concurrent/common-parameters-of-threadpool-workqueue.jpg )
496+
497+ ` PriorityBlockingQueue ` 是一个支持优先级的无界阻塞队列,可以看作是线程安全的` PriorityQueue ` ,两者底层都是使用小顶堆形式的二叉堆,即值最小的元素优先出队。不过,` PriorityQueue ` 不支持阻塞操作并且是有界的。
498+
499+ 要想让 ` PriorityBlockingQueue ` 实现对任务的排序,传入其中的任务必须是具备排序能力的,方式有两种:
500+
501+ 1 . 提交到线程池的任务实现 ` Comparable ` 接口,并重写 ` compareTo ` 方法来指定任务之间的优先级比较规则。
502+ 2 . 创建 ` PriorityBlockingQueue ` 时传入一个 ` Comparator ` 对象来指定任务之间的排序规则(推荐)。
503+
504+ 不过,这存在一些风险和问题,比如:
505+
506+ - ` PriorityBlockingQueue ` 是无界的,可能堆积大量的请求,从而导致 OOM。
507+ - 可能会导致饥饿问题,即低优先级的任务长时间得不到执行。
508+ - 由于需要对队列中的元素进行排序操作,因此会降低性能。
509+
510+ 对于 OOM 这个问题的解决比较简单粗暴,就是继承` PriorityBlockingQueue ` 并重写一下 ` offer ` 方法(入队)的逻辑,当插入的元素数量超过指定值就返回 false 。
511+
512+ 饥饿问题这个可以通过优化设计来解决(比较麻烦),比如等待时间过长的任务会被移除并重新添加到队列中,但是优先级会被提升。
513+
514+ 对于性能方面的影响,是没办法避免的,毕竟需要对任务进行排序操作。并且,对于大部分业务场景来说,这点性能影响是可以接受的。
515+
487516## Future
488517
489518### Future 类有什么用?
Original file line number Diff line number Diff line change @@ -100,7 +100,7 @@ AOP 之所以叫面向切面编程,是因为它的核心思想就是将横切
100100
101101OOP 不能很好地处理一些分散在多个类或对象中的公共行为(如日志记录、事务管理、权限控制、接口限流、接口幂等等),这些行为通常被称为 ** 横切关注点(cross-cutting concerns)** 。如果我们在每个类或对象中都重复实现这些行为,那么会导致代码的冗余、复杂和难以维护。
102102
103- AOP 可以将横切关注点(如日志记录、事务管理、权限控制、接口限流、接口幂等等)从** 核心业务逻辑(core concerns,核心关注点)** 中分离出来,实现关注点的分离。
103+ AOP 可以将横切关注点(如日志记录、事务管理、权限控制、接口限流、接口幂等等)从 ** 核心业务逻辑(core concerns,核心关注点)** 中分离出来,实现关注点的分离。
104104
105105![ ] ( https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/crosscut-logic-and-businesslogic-separation%20%20%20%20%20%20.png )
106106
You can’t perform that action at this time.
0 commit comments