线程池

核心参数

// 默认拒绝策略为 AbortPolicy
public ThreadPoolExecutor(int corePoolSize,
                           int maximumPoolSize,
                           long keepAliveTime,
                           TimeUnit unit,
                           BlockingQueue<Runnable> workQueue,
                           ThreadFactory threadFactory,
                           RejectedExecutionHandler handler) {}

corePoolSize

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

maximumPoolSize

线程池同时执行的最大现场等是maximumPoolSize表示线程池能够容纳同时执行的最大线程数。

keepAlive

表示线程池中的线程空闲时间,当空闲时间达到keepAliveTime值时,线程会被销毁,直到只剩下corePoolSize个线程为止,避免浪费内存和句柄资源。 线程空闲后存活时间, 0代表永远不会消失

timeUnit

时间单位通常是TimeUnit.SECONDS。

workQueue 任务容器

当请求的线程数大于corePoolSize时,线程进入BlockingQueue阻塞队列。后续示例代码中使用的LinkedBlockingQueue是单向链表,使用锁来控制入队和出队的原子性,两个锁分别控制元素的添加和获取,是一个生产消费模型队列

  • ArrayBlockintQueue(有界队列):基于数组的有限阻塞队列,先进先出(FIFO),插入数据和取出数据公用一个锁对象;
  • LinkedBlockingQueue(无界队列):基于链表的无限阻塞队列,先进先出(FIFO),当请求越来越多时(任务处理速度跟不上任务提交速度造成请求堆积)可能导致内存占用过多或OOM,newFixedThreadPool 和 newSingleThreadExecutor 使用这个队列;
  • SynchronousQueue(同步移交队列):不存储元素的阻塞队列,插入操作必须等待一个线程调用移除操作,否则一直会阻塞。newCachedTHreadPool 使用这个队列

ThreadFactory

创建线程的工厂类,默认使用Executors.defaultThreadFactory(),也可以使用guava库的ThreadFactoryBuilder来创建

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

handler

表示执行拒绝策略的对象

• AbortionPolicy (默认):中断直接抛异常
• DiscardPolicy:默默丢弃任务,不进行任何通知
• DiscardOldestPolicy:丢弃打错字了队列中存在时间最久的任务
• CallerRunsPolicy:让提交任务的线程去执行任务

当超过第5个参数workQueue的任务缓存区上限的时候,就可以通过该策略处理请求,这是一种简单的限流保护。

友好的拒绝策略可以是如下三种:

  1. 保存到数据库或者MQ进行削峰填谷,在空闲时取出来执行。
  2. 转向友好的提示页面
  3. 打印日志

直接丢弃任务,将队列头节点元素中的任务丢弃;

构造 ThreadPoolExecutor:

具体查看每个线程池

阻塞队列

new ArrayBlockingQueue();
new LinkedBlockingQueue();
new DelayQueue();
new TransferQueue();
new SynchrousQueue();

非阻塞队列

concurrentlistqueue

低效率并发容器

new Vector();
new Copyonwritelist();
new Hashtable();
synchronized 修饰后的容器
concurrenthashmap
concurrentskiplisthashmap

Executor 用于执行某个任务

ExecutorService 一个服务,在后台一直运行,等待任务抛入(submit),并执行,抛入的任务又分为两个类型:

`Callable` 有返回值

`Runnable` 没有返回值

Executors 是一个用于操作上面对象的工具类和工厂类

ThreadPool 线程池

Future 未来的结果