看看JAVA线程池

前言

这偏文章想写好久了,也经常会去看看线程池方面的东西,但是感觉都好杂,一百个人有一百个人的线程池,这是我的理解,所以在我看来很难接受,所以现在写这篇文章,是想自己整理一下。

起源

起源是来自阿里巴巴的开发规范其中的两点,这里引用一下

1
2
3
4
5
6
7
8
1、线程资源必须通过线程池提供,不允许在应用中自行显示创建线程
说明:线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销,解决资源不足的问题,如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题
2、线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险
说明:Executors返回的线程池对象的弊端如下:
1) FixedThreadPool和SingleThreadPool:
允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM
2) CachedThradPool:
允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM

这是我开始看看线程池的起源,之前也用到过,但也只是局限于用过,没有深入的了解一下各个参数的意义,好了,来看看。

开始

先看看为什么用Executors会导致OOM吧

1
2
3
4
5
6
7
8
9
10
11
Executor executor=Executors.newFixedThreadPool(10);

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}

可以看到在是用Executors创建线程池的时候会去实例化一个ThreadPoolExecutor 然后指定的等待度列里面设置的值为Integer.MAX_VALUE,如果系统长时间运行,就会堆积大量的请求,从而导致OOM

在来看看正确的打开方式,上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* 设置核心池大小
*/
int corePoolSize = 20;
/**
* 设置线程池最大能接受多少线程
*/
int maximumPoolSize = 100;
/**
* 当前线程数大于corePoolSize、小于maximumPoolSize时,超出corePoolSize的线程数的生命周期
*/
long keepActiveTime = 200;
/**
* 设置时间单位,秒
*/
TimeUnit timeUnit = TimeUnit.SECONDS;
/**
* 设置线程池缓存队列的排队策略为FIFO,并且指定缓存队列大小为5
*/
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(5);
/**
* 创建ThreadPoolExecutor线程池对象,并初始化该对象的各种参数
*/
@SuppressWarnings("AlibabaThreadShouldSetName")
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepActiveTime, timeUnit, workQueue);

这是我在项目里面创建的一个线程,目的是接收MQ发过来的消息,由于不确定上游的流量有多少,这里会使用这个线程池

先来解释一下各个参数:

corePoolSize 核心线程数 核心线程会一直存在,当线程数小于核心线程,并且有线程空闲,它也会创建一个新线程去处理

maximumPoolSize 最大线程数 允许当前线程池创建多少线程 ,如果当前线程数量大于核心线程数量 ,并且等待队列已满,则会去创建新的线程去处理

keepAliveTime 等待时间当空闲线程达到这个时间时会退出,直到线程数=核心线程数时

unit 单位单位,就没什么解释的,等待时间的单位

workQueue 工作队列 当线程数大于核心线程数时,就会将当前线程放到等待队列中去。

未完待续。。。

-------------本文结束感谢您的阅读-------------
0%