前言:
有好长一段时间没有写博客了,思来想去,懒是主要的原因,另外一方面笔者在年初换了工作,适应工作还是花了蛮长一段时间的,还有就是,没找到一个合适的主题、系列来写。
之前写的很多对个人的成长还是比较有益的,起码现在在看源码的时候不像前两年那么吃力了,写的代码也会刻意去模仿源码的风格来做。
现在找到一个合适的主题,就是Sentinel,因为公司未来要引入这项技术,所以笔者先前期研究下。
看代码多了的好处就是,大家处理问题的方式大都大同小异,优秀的方式大家都在相互借鉴。笔者也想把这些闪光点单独整理出来。所以暂时的这个系列不会像之前Spring那样给与整体框架分析,而是反过来,从细微处见真章。这样印象应该会更深刻些。当然在最后的时候也是要好好分析一下整体框架的。
注意:后面所使用的Sentinel版本为1.7-Realease版本
1.JDK中关于线程池的使用
线程池是我们大家都比较熟悉的一个点了,当我们想并发执行任务时,首先想到的就是开启多个线程来执行。
最简单的方式莫过于直接创建一个线程任务,如下所示:
new Thread(new Runnable() {
@Override
public void run() {
// do your task here ...
}
}).start();
这样直接创建线程的方式坏处也是显而易见的,当任务过多时,每个任务都创建一个线程,那么大量CPU时间都浪费在线程的切换,而且线程过多时也是会占用大量内存的,所以在实际使用时我们一般也不会采用这种方式(少量任务,新建一两个线程也是可以的)。
下面我们看下JDK提供的直接使用线程池的方案:
// 固定线程池 线程数量为10
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.submit(new Runnable() {
@Override
public void run() {
// do your task here ...
}
});
我们比较常用上述方式来做,那么问题来了,这种方式有什么不好的嘛?
2.阿里代码规范关于线程池的描述
在阿里的代码规范中,有关于线程池的描述,如下
1. 线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
1)FixedThreadPool 和 SingleThreadPool: 允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
2)CachedThreadPool 和 ScheduledThreadPool: 允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。
直接来分析下这段代码:
// Executors.newFixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
// 关于LinkedBlockingQueue 的创建
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
// 可以看到容量基本是不限量,这样当消费速度过慢时,数据会不断的被写入链表,内存有被耗尽的风险
public LinkedBlockingQueue(int capacity) {
if (capacity
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?