其他分享
首页 > 其他分享> > 线程池

线程池

作者:互联网

如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。

为解决此问题,我们需要使用线程池。

java.uitl.concurrent.ThreadPoolExecutor类是线程池中最核心的一个类,下面主要来围绕这个类对线程池进行介绍。

线程池的创建

7个核心参数+4种丢弃策略

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

corePoolSize:  表示常驻核心线程数。如果等于0,则执行完任务之后,没有任何请求进入时销毁线程池的线程;如果大于0,即使本地任务执行完,核心线程也不会被销毁。这个值非常关键,设置过大会浪费资源,过小会导致线程频繁的创建或销毁。

maximumPoolSize: 表示线程池能够同时执行的最大线程数,这个值必须大于1,如果执行的线程数大于此值,则需要借助第5个参数的帮助,缓存在队列中。如果maximumPoolSize与corePoolSize相等,即是固定大小的线程池。

keepAliveTime: 表示线程池中的线程空闲时间,当空闲时间达到keepAliveTime值时,线程会被销毁,直至剩下corePoolSize个线程为止,避免浪费内存和句柄资源。在默认情况下,当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用。但是当ThreadPoolExecutor的allowCoreThreadTimeOut变量值设为true时,核心线程超时后也会被收回。

unit: 表示时间单位。keepAliveTime 的时间单位通常时TimeUnit.SECONDS.

workQueue: 表示缓存队列。当请求的线程数大于maximumPoolSize时,线程进入BlockingQueue阻塞队列。

threadFactory: 表示线程工厂。他用来生产一组相同任务的线程。线程池的命名是通过给这个factory增加组名前缀名来实现的。在虚拟机栈分析时就可以知道线程任务是有哪个线程工厂来产生的。

handler: 表示执行拒绝策略的对象。当超过第5个参数workQueue的任务缓存区上限时,就可以通过该策略处理对象,这是一种简单的限流保护。

拒绝策略主要包含:

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。 
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务 

由这些参数可知,线程池的工作过程如下:

1. 线程池刚创建时,里面没有一个线程。任务队列是作为参数传进来的。不过,就算队列里面 有任务,线程池也不会马上执行它们。

2. 当调用 execute() 方法添加一个任务时,线程池会做如下判断:   

  a) 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;   

  b) 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列;   

  c) 如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还是要 创建非核心线程立刻运行这个任务;   

  d) 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池 会抛出异常 RejectExecutionException。

3. 当一个线程完成任务时,它会从队列中取下一个任务来执行。

4. 当一个线程无事可做,超过一定的时间(keepAliveTime)时,线程池会判断,   

  如果当前运 行的线程数大于 corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它 最终会收缩到 corePoolSize 的大小。

标签:corePoolSize,keepAliveTime,队列,任务,线程,ThreadPoolExecutor
来源: https://www.cnblogs.com/Hyacinth-Yuan/p/15680359.html