线程池是什么
Java中的线程池是通过java.util.concurrent.ThreadPoolExecutor类来实现的, 线程池 (ThreadPool) 是一种基于池化概念的多线程处理技术。在创建和启动线程时,会涉及大量的系统开销。为了减少创建和销毁线程的开销,提高系统性能,线程池被广泛使用。
在Java中,java.util.concurrent.ExecutorService 是线程池的核心接口,而java.util.concurrent.Executors 是一个工厂类,提供了创建各种线程池的方法。通常会通过Executors来创建线程池。
Executors自带线程池
常用的线程池类型包括:
-
newFixedThreadPool- 创建一个固定大小的线程池,超出的线程会在队列中等待。
-
newCachedThreadPool- 创建一个可缓存的线程池,如果线程池长度超过处理需要,可灵活回收空闲线程。
-
newSingleThreadExecutor- 创建一个单线程化的Executor,它只会用唯一的工作线程来执行任务。
-
newScheduledThreadPool- 创建一个定长线程池,支持定时及周期性任务执行。
线程池的主要参数:
-
corePoolSize- 线程池的基本大小,即在没有任务需要执行的时候线程池的大小,并且只有在工作队列满了的情况下才会创建超出这个数量的线程。
-
maximumPoolSize- 线程池最大大小,这个参数也就是线程池能够容纳的最大线程数。这个参数在任务队列满了,或者
corePoolSize满了之后,线程池会创建新的线程执行任务。
- 线程池最大大小,这个参数也就是线程池能够容纳的最大线程数。这个参数在任务队列满了,或者
-
keepAliveTime- 线程空闲时的存活时间,即线程没有任务执行时,继续存活的时间。默认情况下,该参数只有在线程数大于
corePoolSize的时候才有用。
- 线程空闲时的存活时间,即线程没有任务执行时,继续存活的时间。默认情况下,该参数只有在线程数大于
-
unit-
keepAliveTime的时间单位,时、分、秒、毫秒等
-
-
workQueue-
工作队列,用于存放待执行的任务。这个参数的选择也很重要,会对线程池的运行过程产生重大影响。一般来说,这个参数的选择主要考虑任务的性质(CPU密集型还是IO密集型)以及任务的优先级等因素。
-
这是一个阻塞队列,用于存放等待执行的任务。当线程池中的线程数达到
corePoolSize后,新提交的任务就会被放到这个队列中,当队列也满了之后,才会开始创建超过corePoolSize的线程。workQueue的选择对于线程池的性能和行为影响很大 -
java.util.concurrent包下提供了以下几种队列: -
ArrayBlockingQueue- 基于数组的有界阻塞队列,按 FIFO(先进先出)原则对元素进行排序。
-
LinkedBlockingQueue:- 基于链表的阻塞队列,按FIFO排序元素,吞吐量通常要高于
ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。
- 基于链表的阻塞队列,按FIFO排序元素,吞吐量通常要高于
-
SynchronousQueue- 不存储元素的阻塞队列,或者说是一个无缓冲的队列,它直接将任务交给线程而不保持它们。静态工厂方法
Executors.newCachedThreadPool()使用了这个队列。
- 不存储元素的阻塞队列,或者说是一个无缓冲的队列,它直接将任务交给线程而不保持它们。静态工厂方法
-
PriorityBlockingQueue:- 具有优先级的无界阻塞队列。
-
-
threadFactory- 线程工厂,主要用来创建线程。这是一个接口,用来创建新线程。默认的实现会创建一个新的、非守护的线程,然后将线程的优先级设置为
Thread.NORM_PRIORITY,最后设置一个系统默认的UncaughtExceptionHandler。 - 这个参数允许你自定义如何创建、初始化和启动新线程。例如,你可以使用它来设置线程的名字,线程组,优先级,守护状态,以及
UncaughtExceptionHandler。如果没有提供自定义的ThreadFactory,线程池会使用默认的ThreadFactory。 -
Executors类还提供了另一种ThreadFactory的实现,即Executors.privilegedThreadFactory()它是一个具有与Executors.defaultThreadFactory()相同的设置,但新创建的线程具有与创建线程相同的访问控制上下文和权限的工厂
- 线程工厂,主要用来创建线程。这是一个接口,用来创建新线程。默认的实现会创建一个新的、非守护的线程,然后将线程的优先级设置为
-
handler-
表示当拒绝处理任务时的策略,有以下四种取值:
-
ThreadPoolExecutor.AbortPolicy- 丢弃任务并抛出
RejectedExecutionException异常。
- 丢弃任务并抛出
-
ThreadPoolExecutor.DiscardPolicy- 也是丢弃任务,但是不抛出异常。
-
ThreadPoolExecutor.DiscardOldestPolicy- 丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)。
-
ThreadPoolExecutor.CallerRunsPolicy- 由调用线程处理该任务。
-