线程池七大核心参数

哎哟,你说的有道理,不过说实话,我刚接手一个系统的时候,对于七个线程池的设置是很困惑的。
但慢慢想想,我发现自己确实遇到了很多坑。
我给大家讲一下我遇到的具体情况。

当时我接手了一个项目,高峰期系统卡住了。
我检查了一下,发现线程池配置不正确。
主线程数量太少。
结果任务一到,新的线程就陆续创建,直接烧毁CPU。
我记得那是2 01 8 年,在上海,服务器温度高达5 0多度,客户愤怒不已。

后来我把它改成了主线程数,并根据历史最大任务量来设置。
例如,我计算出平均每秒有5 0个任务,所以我将主线程设置为4 0,大多数情况下已经足够了。
当高峰期到来时,您可以临时添加一些,但不会一次创建很多。

另一个例子是最大线程数。
一开始我设置太高了,但是队列爆炸了,新任务提交直接被拒绝,客户无法提交订单,所以他给我回了电话。
我对其进行了修改以查看队列大小和当前线程数。
如果队列几乎已满并达到最大线程数,我将使用丢弃策略,例如丢弃最旧的,或保存它并稍后重试。

我也有线程生存时间的问题。
一开始时间太短了。
结果,非必要的线程不断被创建和销毁,导致系统开销很高。
后来我把时间调长一些,比如3 0秒,发现效果好多了。
我记得那是2 02 0年的事了,改了之后,系统反应速度快多了。

对于任务队列,我选择了LinkedBlockingQueue,它基于链表,具有很好的公平性。
但要注意的是,队列大小必须设置正确。
如果太小,任务会出现延迟;如果太大,内存会不够。
在我当时的项目中,我根据内存大小和估计的并发度来设置队列大小。

线程优先级,我一般不怎么碰,默认就行了。
但是,如果您的任务的紧急程度不同,例如某些任务需要高优先级处理,那么您就需要对其进行调整。
我有一个朋友建立了一个抢购系统。
它提高了紧急采购任务线程的优先级。
结果,系统在匆忙的采购过程中变得更加稳定。

拒绝策略,必须有替代方案。
我通常使用 DiscardOldest 删除最旧的任务,以便仍然可以运行新任务。
但你什么也做不了。
如果客户不能提交任务,你肯定不会做。

线程工厂,我一般都用默认的,没怎么改。
但如果你需要它,例如将线程设置为守护线程或设置优先级,你需要自定义它。

简单来说,线程池设置应根据您的实际活动进行调整。
不要抄袭别人的工作,自己尝试一下,看看系统是如何工作的。
这项工作不能操之过急。

线程池七大核心参数

嗯,线程池的参数相当多,其中有7 个核心参数。
只有理解了它,才能有效地使用它。

1 . corePoolSize(核心线程数) 这是要保留的最小线程数。
即使空闲也不会被丢弃,除非打开了allowCoreThreadTimeOut。
例如,如果设置 corePoolSize=5 ,则池中至少有 5 个线程。
即使无所事事,这五根线也永远不会消失。
当有任务到来时,首先检查是否有足够的线程。
如果没有,请开始一个新线程。

2 MaximumPoolSize(最大线程数) 当线程数量达到 corePoolSize 时,线程就满了。
我应该如何处理我的新任务?首先,排队。
如果队列也满了怎么办?打开一个新线程,但该线程不会无限期地打开,直到达到maximumPoolSize。
例如,如果设置maximumPoolSize=1 0,则线程数最多为1 0个,并且将根据拒绝策略处理额外的任务。

3 KeepAliveTime(空闲线程生存期) 线程处于空闲状态,无事可做。
如果当前线程数大于 corePoolSize,则在指定时间后线程被杀死。
例如,如果KeepAliveTime=6 0秒(以秒为单位),则空闲时间超过6 0秒的线程将被回收。

4 .单位(unit) KeepAliveTime的单位是秒、毫秒等,没有什么特别要说的。

5 workQueue(任务队列) 我首先将任务放在这里,当线程空闲时,我从队列中取出它。
常见的有LinkedBlockingQueue、ArrayBlockingQueue等,当队列满了你做什么取决于你的拒绝策略。

6 threadFactory(线程工厂) 它在创建新线程时使用,并允许您自定义线程名称以及是否为守护线程等内容。
例如,如果创建一个工厂,所有线程都将是“my-pool-thread-”+索引,这对于读取日志很有用。

7 .Handler(拒绝策略) 队列已满,线程也已满。
新任务我应该做什么?我需要制定拒绝策略。
常见的有AbortPolicy(直接抛出异常)、CallerRunsPolicy(让提交任务的线程自己运行)、DiscardPolicy(直接丢弃)、DiscardOldestPolicy(丢弃队列中最旧的任务)。

---
线程池模式
1 .半同步/半异步模式(生产者/消费者模式) 这是最常见的模型,具有三层:同步层、队列层和异步层。

同步层:主线程运行并排队任务。

队列层:任务排队等待线程获取。

异步层:工作线程从队列中获取任务。
如果队列为空,线程将挂起等待任务。
适合数据量较小的情况。
数据在线程之间交换,因此不适合大量数据。

2 .Leader-Follower模型(Leader-Follower) 线程具有三种状态:领导者、追随者和工作者。

永远只有一位领导者。

当事件发生时,领导者广播新闻,选择一个追随者成为新的领导者,并自己成为工人。

一旦工作完成,工人就成为仆人。
这种模式比较复杂,但避免了线程之间的直接数据传输,导致CPU缓存使用率更高。
这是在 ACE 框架中实现的。

说实话,用过多次你就会明白这一点。
适当调整参数将带来高效率。
如果参数调整不当,就会卡住或耗尽资源。
你必须一一尝试。
当时我不明白为什么这么复杂,但是做了很多次之后,我发现这确实是一项技术活。

线程池的7大参数是什么

上周 线程池参数确实非常重要。

核心线程数(corePoolSize) 也就是说,至少必须在槽中留下几根线。
即使你很懒,也可以在不设置超时的情况下运行。

最大线程数(maximumPoolSize) 池中可以打开的最大数量。
核心加上临时计数。

保持活动时间 只要临时线程不活动,就会重复使用它。

时间单位(unit) KeepAliveTime用什么单位来衡量?秒 毫秒。

工作队列(workQueue) 将作业放在队列中的第一个位置。
有界又无边。

棉花厂(棉花厂) 如何编织。
名称优先级守护线程等
拒绝策略(处理程序) 如果队列满了但人不够怎么办?抛出异常;抛出你自己的线程。

2 02 3 这些参数相互影响。
核心线程正忙,作业正在排队。
当队列已满时,创建一个临时字符串。
当你达到最高级别时,如果你还有工作,请遵循拒绝策略。

那个朋友 当临时线程空闲且超时时。
它被回收利用。

算了。