线程池详解

前提:线程池创建有两种方式,一种是Executors使用默认方法创建,另一种是通过ThreadPoolExecutor自定义,不推荐前者是因为前者的配置很多都是取得integer得最大值,很容易造成OOM

1、线程池核心概念:

int corePoolSize 核心线程数
int maximumPoolSize 最大线程数
long keepAliveTime 核心线程数满了之后创建的最大线程多久后释放
TimeUnit unit 释放时间的单位,m,h,d
BlockingQueue

2、详细解释

2.1 核心线程数

当线程是IO密集型时,主要消耗磁盘的读写性能,可以设置为2*n,n为当前服务器核数(比如8核16G的服务器设置为16,Runtime.getRuntime().availableProcessors()获取)

当线程是CPU密集型时,主要消耗cpu性能,设置为n+1

2.2最大线程数

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:b70f282f-b2ff-4d48-b5bf-d3a12c98f781

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:8f172373-c3aa-4440-9bcc-27f867478948

2.3 阻塞消息队列

ArrayBlockingQueue:基于数组的先进先出队列,此队列创建时必须指定大小,读写用一把锁,性能较差;

LinkedBlockingQueue:基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE;一般是用这个,指定了大小则限制具体大小,写核读分两把锁进行操作,所以性能较好

synchronousQueue:这个队列比较特殊,它不会保存提交的任务,而是将直接新建一个线程来执行新来的任务。

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:e1311d09-8233-46d3-aff0-0bfdfb90958c

[En]

[TencentCloudSDKException] code:FailedOperation.ServiceIsolate message:service is stopped due to arrears, please recharge your account in Tencent Cloud requestId:c8af0522-372b-4f4a-88bf-a6c7e8c915f0

2.4 线程工厂

创建线程的类,可以用默认工厂,也可以自定义线程工厂实现 implements ThreadFactory类,实现newThread方法,自定义工厂的话可以设置线程名或者定义辅助线程

2.5拒绝策略

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。

ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务

ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务

线程池详解

自定义拒绝策略

需要继承implements RejectedExecutionHandler 实现public void rejectedExecution(Runnable r, ThreadPoolExecutor executor)方法,此方法中可以通过类型转换的形式拿到线程具体的类,从而获取线程相关信息,详细代码见下方详细代码,需要注意的是,只能转换线程池execute的Runnable类,如果线程池执行的线程是通过实现Callable完成的,在执行前会把线程封装成FutureTask,这样相当于转换再转换,就没法转换成原来的对象了。

备注:execute只能提交Runnable线程,submit可以提交所有的Runnable、Callable、Thread线程

Original: https://www.cnblogs.com/xiufengd/p/15933223.html
Author: 程序员丁先生
Title: 线程池详解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/562507/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球