一、什么是线程池
和进程相比线程的创建和消费的开销的确很小,但是随着业务的发展,线程使用的频次越来越多,创建和销毁线程的开销也越来越大,使用线程池就能改善线程频繁的创建和开销。线程池就是系统提前申请好一些线程放在一个地方,当我们要使用多线程的时候直接拿出来使用,用完之后再还回到这个地方,这个就避免了线程的频繁创建与开销,这样就能提高整体的效率。所以线程池最大的好处就是减少每次启动、销毁线程的损耗。
二、ThreadPoolExecutor
在Java标准库中提供了ThreadPoolExecutor这个类,让我们来使用线程池。但是这个类使用起来有点麻烦,当我们要new出这个类的对象的时候,需要传入很多参数。
上图就是 ThreadPoolExecutor 提供的构造方法,下面我们介绍最后一个构造方法里参数的意义。
1.int corePoolSize 和 int maximumPoolSize
corePoolSize 表示线程池的核心线程数,maximumPoolSize表示线程池的最大线程数。核心线程数表示的是一个线程池在正常使用中的线程数量,它会一直存在于线程池中,线程池提供了线程扩容的功能,当核心线程数满足不了需求的时候,线程池就会创建出新的线程来使用,新创建的线程为非核心线程,当线程池空闲的时候,非核心线程就会被销毁,最大线程数就是核心线程数与非核心线程数的和。
2.long keepAliveTime 和 TimeUnit unit
keepAliveTime表示非核心线程空闲多长时间后被销毁,unit表示keepAliveTime的时间单位,当一个线程池空闲下来的时候,非核心线程不会立刻被销毁,会根据keepAliveTime 设置的时间来销毁线程。unit是一个枚举类型,里面的枚举常量为:
3.BlockingQueue <Runnable> workQueue
workQueue表示工作队列,在线程池中,通过submit方法来向线程池递交线程任务,这时就需要一个阻塞队列。submit递交上来的任务就存放在这个队列里面,线程池也向这个队列里面取要执行的任务,当我们传递这个队列的时候就可以自己指定这个队列的大小以及类型。
4. ThreadFactory threadFactory
ThreadFactory threadFactory 指的是 '线程工厂' 是Thread类的工厂类,通过这个类可以完成Thread的实例创建和初始化工作 ,工厂是指一种工厂设计模式,是一种常见的设计模式。工厂设计模式是一种在类创建实例的时候使用的一种设计模式。threadFactory: 创建线程的工厂,参与具体的创建线程工作。通过不同线程工厂创建出的线程相当于对⼀些属性进行了不同的初始化设置。
5.RejectedExecutionHandler handler
RejectedExecutionHandler表示的是拒绝策略,指的是当线程池的任务超出负荷后的处理方式,有四种拒绝策略:
1.AbortPolicy(): 超过负荷,直接抛出异常
2.CallerRunsPolicy():调用者负责处理多出来的任务
3.DiscardOldestPolicy():丢弃队列中最⽼的任务.
4.DiscardPolicy():丢弃新来的任务.
三、Executors的使用
在Java中还提供了Executors类,可以更加方便的来构造出线程池
Executors类常使用的方法
代码实例 :
代码结果: