先回顾下类关系图:
一般的使用方式:这里不用Executors帮助类,而是构建自己的线程池:
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Created by Administrator on 2016/7/21.
*/
public class ThreadPoolUtil {
private static ThreadPoolUtil threadPoolUtil;
private static ThreadPoolExecutor poolExecutor;
//核心线程数
private int corePoolSize = 5;
//最大线程数据
private int maximumPoolSize = 5;
private ThreadPoolUtil() {
poolExecutor = new ThreadPoolExecutor(corePoolSize,
maximumPoolSize,
0L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ThreadPoolUtil newInstance() {
if (threadPoolUtil == null) {
synchronized (ThreadPoolUtil.class) {
if (threadPoolUtil == null) {
threadPoolUtil = new ThreadPoolUtil();
}
}
}
return threadPoolUtil;
}
public void execute(Runnable task) {
poolExecutor.execute(task);
}
/**
* 执行需要返回结果的任务
*/
public Future<Runnable> execute(Callable<Runnable> task) {
return poolExecutor.submit(task);
}
}
简单的使用方式:
ThreadPoolUtil poolUtil = ThreadPoolUtil.newInstance();
poolUtil.execute(new Runnable() {
...});
poolUtil.execute(new Runnable() {
...});
poolUtil.execute(new Runnable() {
...});
.
.
.
首先了解下构造函数的各个参数含义:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSize : 核心线程数,也就是线程池中保持存活的线程有多少,包括正在执行任务和空闲的。
maximumPoolSize:最大线程数,也就是核心线程数全部都在执行任务,没有空闲的出来,且等待队列也已经装载满了,然后后又有新的任务需要执行,这时就会开启新的线程来执行,但总线程数:corePoolSize+newThreadSize <= maximumPoolSize。
keepAliveTime:多出的空闲线程存活的时间,也就是当前线程数大于核心线程数的这部分: nowThreadSize(当前线程总数) - corePoolSize 这部分的线程。
unit :线程存活的时间单位:有秒、分、时等等
workQueue :存放等待执行的任务队列
threadFactory :创建线程的工厂类、一般使用默认Executors.defaultThreadFactory()。
handler:处理多出的任务策略,也就是等待队列已满,最大线程数量中都没有空闲线程,此时还是有任务提交过来,就需要进行处理。有抛异常、不处理等。
提出问题:既然已经规定了核心线程数和最大线程数,当我们不断向线程池提交任务的时候,内部是否会进行开启核心线程数的线程进行并行执行任务,当再有任务提交的时候,就会放到等待队列中,直到队列满了,再开启线程来执行,当线程数据大于maximumPoolSize时,是否进行handler策略处理。
代码验证四部曲:
1.当需执行任务数小于核心线程数,池中的线程是否一开始就维持核心线程数的数量。
2.当执行任务数大于核心线程数,该任务是暂存在队列中还是立即开启新的线程执行。
3.当池中线程数量达到最大线程数时,且无空闲线程,队列也已经满了,此时还有新的任务提交过来,是否执行处理策略。
首先看已修改的类:
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Created by Administrator on 2016/7/21.
*/
public class ThreadPoolUtil {
private static ThreadPoolUtil threadPoolUtil;
private static ThreadPoolExecutor poolExecutor;
//核心线程数
private int corePoolSize = 2;
//最大线程数据
private int maximumPoolSize = 5;
//创建等待队列大小而2
private LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(2);
private ThreadPoolUtil() {
poolExecutor = new ThreadPoolExecutor(corePoolSize,
maximumPoolSize,
0L,
TimeUnit.SECONDS,
queue,
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
}
public static ThreadPoolUtil newInstance() {
if (threadPoolUtil == null) {
synchronized (ThreadPoolUtil.class) {
if (threadPoolUtil == null) {
threadPoolUtil = new ThreadPoolUtil();
}
}
}
return threadPoolUtil;
}
public void execute(Runnable task) {
poolExecutor.execute(task);
}
/**
* 执行需要返回结果的任务
*/
public Future<Runnable> execute(Callable<Runnable> task) {
return poolExecutor.submit(task);
}
/**
* 获取当前执行任务的线程数
* @return
*/
public int getCurrentThreadNum(){