ThreadPoolExecutor使用

一. ThreadPoolExecutor的构造参数

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,
                          TimeUnit unit, BlockingQueue<runnable> workQueue,
                          ThreadFactory threadFactory,RejectedExecutionHandler handler)

ThreadPoolExecutor一共有7个参数,下面是每个参数的意义

参数名 类型 说明
corePoolSize int 核心线程数
maximumPoolSize int 线程池中最大线程数
keepAliveTime long 除核心线程外,其他线程空闲时间,
配置了allowCoreThreadTimeOut之后
该属性也可作用于很线程
unit TimeUnit 和keepAliveTime搭配使用
workQueue BlockingQueue 工作队列
threadFactory ThreadFactory 线程创建工厂
handler RejectedExecutionHandler 线程池拒绝策略

二. corePoolSize和maximumPoolSize

corePoolSize和maximumPoolSize这两个参数使用来控制线程池大小的参数,ThreadPoolExecutor会根据这两个参数的值来动态的调整线程池的大小,将这两个属性的值设置成一样,就会得到一个固定大小的线程池。ThreadPoolExecutor在接受一个任务时主要分为三个步骤,如下图。

graph LR Start(Submit Task)-->core{"WorkSize>corePollSize"} core--是-->queue{"WorkQueue is full"} queue--是-->maxpool{"WorkSize>maxPoolSize"} maxpool--是-->Reject core--否-->new("Execute Task ") queue--否-->addToQueue("addToQueue ") maxpool--否-->newTask("Execute Task ")
  1. 通过public void execute(Runnable command)方法来提交一个一个任务
  2. 判断当前工作线程数是否大于核心线程数,否则创建一个新的线程执行该任务
  3. 如果大于当前核心线程则尝试放入工作队列中进行等待
  4. 如果工作队列已满,则判断工作线程数是否大于最大线程数,是则根据RejectedExecutionHandler拒绝该任务,否则创建一个新的线程执行该任务

总结上面的流程我们可以看出,线程池方式的优点:

  1. 合理控制并发的线程数,将执行的工作线程数控制在核心线程数,合理利用系统资源
  2. 合理管理线程的创建和销毁,我们知道线程的创建是十分消耗系统资源的,而通过线程池的方式,可以不必频繁的创建线程,可以利用线程池中空闲的线程资源来执行任务。在系统空闲线程不够的情况下才会去创建新的线程,这样在密集任务执行时可以合理利用线程资源。在默认情况下,只有新任务进来时,才会去创建核心线程,不过你可以通过public boolean prestartCoreThread()public int prestartAllCoreThreads()去创建一个或所有核心线程。

三. JDK内置的集中线程池

java.util.concurrent.ExecutorsJAVA已经为我们实现好了集中常用的线程池.。

  1. FixedThreadPool创建一个固定线程数的线程池,其实就是将ThreadPollExecutor的核心线程数和最大线程数两个属性设置成一样的值,可以用来控制并发数.
public static ExecutorService newFixedThreadPool(int nThreads);
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory);
  1. CachedThreadPool创建一个可缓存的线程池,在收到一个任务时,会在空闲的线程中去一个出来执行任务,如果没有则会创建一个新的线程去执行任务,适合短期的大量的异步任务。CachedThreadPool的核心线程数设置的为0,每次都是从工作队列中去执行任务,代码中设置的超时时间是60秒,这样在超过60秒之后,空闲的线程就会被回收,不会出现占用系统资源的情况。

  2. public static ExecutorService newCachedThreadPool();
    public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory);
    
  3. SingleThreadExecutor创建一个只有一个工作线程的线程池,线程池中只有一个线程去执行任务,可以控制任务的顺序性。

    public static ExecutorService newSingleThreadExecutor();
    public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory);
    
  4. SingleThreadScheduledExecutor创建只有一个工作线程的可执行周期性任务的线程池,它除了可以像其他的线程池一样可以执行异步任务,也支持执行定时任务。

    public static ScheduledExecutorService newSingleThreadScheduledExecutor();
    public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory);
    

ThreadPoolExecutor使用

上一篇:查询某人在一月份所任职的部门


下一篇:str和dumps的区别