概念
使用ThreadPoolExecutor创建
JDK1.8中构造方法如下:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
| 变量 | 意义 |
|---|---|
| corePoolSize | 核心线程池大小 |
| maximumPoolSize | 最大线程池大小 |
| keepAliveTime | 空闲线程的存活时间 |
| unit | 空闲线程保持存活的时间的单位。 |
| workQueue | 阻塞任务队列,当要执行的任务超出corePoolSize ,那么此时将把任务放入队列中。 |
| handler | 提交任务超出maxmumPoolSize+workQueue时的拒绝策略 |
存活时间
keepAliveTime即空闲线程(大于corePoolSize 小于maximumPoolSize 的线程)保持存活的时间,超出这个时间,线程将被销毁。
存活时间单位
TimeUnit.NANOSECONDS // 千分之一微秒(纳秒)
TimeUnit.MICROSECONDS // 千分之一毫秒(微妙)
TimeUnit.MILLISECONDS // 千分之一秒(毫秒)
TimeUnit.SECONDS // 秒
TimeUnit.MINUTES // 分
TimeUnit.HOURS // 小时
TimeUnit.DAYS // 天
任务队列
- ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。
- LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按 FIFO (先进先出) 排序元素,吞吐量通常要高于 ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool() 使用了这个队列。
- SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool 使用了这个队列。
- PriorityBlockingQueue:一个具有优先级的无限阻塞队列。
拒绝策略
- AbortPolicy 中止策略 :默认的饱和策略,该策略将抛出为检查的RejectedExecutionException.调用者可以捕获这个异常,然后根据需求编写自己的代码。
- DiscardPolicy 抛弃策略: 当新提交的任务无法保存到队列中等待执行时,抛弃策略会悄悄抛弃该任务
- DiscardOldestPolicy 抛弃最旧的策略: 抛弃下一个将被执行的任务,然后添加新提交的任务
- CallerRunsPolicy 调用者运行策略: 该策略实现了一种调用机制,该策略既不抛弃任务,也不抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量。它不会在线程池的某个线程中执行新提交的任务,而是在一个调用了execute的线程中执行该任务(一般该调用者是main线程)
小demo
public class ThreadPoolDemo implements Callable<String> {
/**
* 核心线程池大小
*/
public static final int CORE_POOL_SIZE = 5;
/**
* 最大线程池大小
*/
public static final int MAX_POOL_SIZE = 10;
/**
* 阻塞任务队列大小
*/
public static final int QUEUE_CAPACITY = 100;
/**
* 空闲线程存活时间
*/
public static final Long KEEP_ALIVE_TIME = 1L;
@Override
public String call() throws Exception {
return Thread.currentThread().getName();
}
public static void main(String[] args) {
//通过ThreadPoolExecutor构造函数自定义参数创建
ThreadPoolExecutor executor = new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAX_POOL_SIZE,
KEEP_ALIVE_TIME,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(QUEUE_CAPACITY),
new ThreadPoolExecutor.CallerRunsPolicy());
List<Future<String>> futureList = new ArrayList<>();
Callable<String> callable = new ThreadPoolDemo();
for (int i = 0; i < 10; i++) {
//提交任务到线程池
Future<String> future = executor.submit(callable);
//将返回值 future 添加到 list,我们可以通过 future 获得 执行 Callable 得到的返回值
futureList.add(future);
}
//获取返回结果
for (Future<String> fut : futureList) {
try {
System.out.println(new Date() + "::" + fut.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
//关闭线程池
executor.shutdown();
}
}