博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
三:线程池类关系和参数解析
阅读量:4212 次
发布时间:2019-05-26

本文共 2874 字,大约阅读时间需要 9 分钟。

        上一个章节,我们介绍了线程的状态,这一次我们进入到线程池的学习,线程池我们分为3篇文章来介绍他,当前为第1篇,后续还有四:创建线程池的方式篇,还有五:线程池的源码深度解析篇。

当前篇我们分为2个两点来说明:

什么是线程池?

线程池类关系?

线程池定义的参数解析

1.什么是线程池?

        网上你可以搜索到很多答案,我这里用通俗的话语来解释一下。Thread t1 = new Thread()代表创建了一个线程Thread对象,多线程简单的理解为创建多个Thread对象,而线程池,就是提供一个池子,来统一的创建,分配,管理这些多个线程。

2.类关系

        线程池中,用到了很多的类,比如:
Executor,ExecutorService,AbstractExecutorService,ThreadPoolExecutor等;有可能你一开始觉得很混乱,名字都差不多。那么我们来结合源码看一下,直接放出这4个类(或接口)的部分源码:
1)ThreadPoolExecutor

public class ThreadPoolExecutor extends AbstractExecutorService {

2)AbstractExecutorService

public abstract class AbstractExecutorService implements ExecutorService {

3)ExecutorService

public interface ExecutorService extends Executor {

4)Executor

public interface Executor {

仔细看,都是一级级往上继承的,所以他们的继承关系为:

(又到了不喜欢画图环节):
在这里插入图片描述
3.线程池参数解析
我们先来看一下线程池的默认构造函数:

public ThreadPoolExecutor(int corePoolSize,                              int maximumPoolSize,                              long keepAliveTime,                              TimeUnit unit,                              BlockingQueue
workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }

别急,一个个来:

1)corePoolSize:线程池中核心线程数的数量。

2)maximumPoolSize:线程池中允许创建线程的最大数量。

3)keepAliveTime:这个参数代表允许线程处于空闲的时长。

注意:只有当线程池中的已被创建的线程数量大于核心线程数(corePoolSize)时,这个参数才会起作用。如果线程处于空闲时长超过了这个参数数值,那么该线程就会终止。
这里还要讲到一个参数allowCoreThreadTimeOut,他是决定该参数生效的条件。
我们来看一下该参数的源码解释:

/**如果为false(默认),则即使处于空闲状态,核心线程也会保持活动状态。如果为true,则核心线程使用keepAliveTime来超时等待工作*/private volatile boolean allowCoreThreadTimeOut;意思就是:1.如果allowCoreThreadTimeOut=false,那么当线程池中线程数量大于核心线程数时,核心线程处于活跃,非核心线程会有空闲超时;2.如果allowCoreThreadTimeOut=true,那么没有任何条件,所有线程都会有空闲超时

4)TimeUnit

超时时间单位

5)workQueue

等待线程执行的阻塞队列,默认为:BlockingQueue,还可以换成:
ArrayBlockingQueue;
LinkedBlockingQueue;
SynchronousQueue;

6)threadFactory

顾名思义:线程工厂,用来创建线程,看他的源码:
用了volatile关键字,用来保证线程工厂的可见性,同时禁止指令重排序;

private volatile ThreadFactory threadFactory;

7)handler

拒绝策略,当线程池根据一定条件,发现无法新添加任务的时候,会作出相对应的拒绝任务策略,一般有以下几种,我们来看一下源码:

final void reject(Runnable command) {
handler.rejectedExecution(command, this); }

看他的实现类:

在这里插入图片描述
1)AbortPolicy:丢弃任务并且抛出一个异常:RejectedExecutionException
2)CallerRunsPolicy:如果调用线程没有被关闭,那么就由调用线程来处理
3)DiscardOldestPolicy:丢弃最老的未处理任务,尝试执行新任务
4)DiscardPolicy:丢弃任务不处理,不抛出异常

看到这里,你应该对线程池有了一个基本的框架概念,对线程池的参数有了一定的认识;

下一篇:

转载地址:http://sikmi.baihongyu.com/

你可能感兴趣的文章
ARC MRC 变换
查看>>
Swift cell的自适应高度
查看>>
【linux】.fuse_hiddenXXXX 文件是如何生成的?
查看>>
【LKM】整合多个LKM为1个
查看>>
【Windows C++】调用powershell上传指定目录下所有文件
查看>>
Java图形界面中单选按钮JRadioButton和按钮Button事件处理
查看>>
小练习 - 排序:冒泡、选择、快排
查看>>
SparkStreaming 如何保证消费Kafka的数据不丢失不重复
查看>>
Spark Shuffle及其调优
查看>>
数据仓库分层
查看>>
常见数据结构-TrieTree/线段树/TreeSet
查看>>
Hive数据倾斜
查看>>
TopK问题
查看>>
Hive调优
查看>>
HQL排查数据倾斜
查看>>
DAG以及任务调度
查看>>
LeetCode——DFS
查看>>
MapReduce Task数目划分
查看>>
ZooKeeper分布式锁
查看>>
3126 Prime Path
查看>>