demo代码:
public class ThreadPoolExecutorSample {
public static void main(String[] args) throws IOException, InterruptedException {
//阻塞队列,大小设置为2,方便查看运行过程
int blockQueueSize = 2;
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(blockQueueSize);
//线程工厂,可以为线程池启动的线程做一些自定义的处理,比如做标识方便区分查看结果
ThreadFactory threadFactory = new MyTreadFactory();
//拒绝策略,比如拒绝执行了可以在里面自定义一些返回内容
RejectedExecutionHandler handler = new MyIgnoreHandle();
//核心线程数为2,最大线程数为3,空闲时间为10,设置小点是为了方便打印查看执行过程
int corePoolSize = 2;
int maximumPoolSize = 3;
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 2000, TimeUnit.SECONDS, workQueue, threadFactory, handler);
//这里是预启动所有的核心线程,不加这句话如果没有任务的情况下线程池里是没有线程的
//executor.prestartAllCoreThreads();
for (int i = 1; i <= 10; i++) {
MyTask task = new MyTask(String.valueOf(i));
executor.execute(task);
Thread.sleep(10);
}
}
static class MyTreadFactory implements ThreadFactory {
private final AtomicInteger mThreadNum = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
String name = "";
if(mThreadNum.get()<=2){
name = "my-thread-" + mThreadNum.get() + "-核心线程";
}
else{
name = "my-thread-" + mThreadNum.get() + "-非核心线程";
}
Thread t = new Thread(r, name);
System.out.println(t.getName() + " has been created");
mThreadNum.getAndIncrement();
return t;
}
}
static class MyIgnoreHandle implements RejectedExecutionHandler {
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
//这里是可以重写拒绝队列的,比如一些不允许拒绝的任务我们可以写到redis缓存里,再专门开一个线程来重新执行拒绝的任务
//这里就简单做日志输出记录了
doLog(r, e);
}
private void doLog(Runnable r, ThreadPoolExecutor e) {
System.err.println( r.toString() + " rejected");
}
}
static class MyTask implements Runnable {
private String name;
public MyTask(String name) {
this.name = name;
}
@Override
public void run() {
try {
System.out.println(this.toString() + " is running!");
//让任务执行慢点
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public String getName() {
return name;
}
@Override
public String toString() {
return "MyTask [name=" + name + "]";
}
}
}
demo参数设置:
阻塞队列数:2
核心线程数为:2
最大线程数为:3,那非核心线程数只有1个
执行结果:
demo执行结果分析:
在1-10的for循环体里:
1.任务1进来,此时线程池还没有线程,线程池此时会创建第1个核心线程来执行任务。
2.任务2进来,此时线程池只有1个核心线程,线程池此时会创建第2个核心线程来执行任务2。
3.任务3进来,此时线程池已经有2个核心线程,达到预设的核心线程数,任务3只能去阻塞队列排队了。
4.任务4进来,此时线程池已经有2个核心线程,达到预设的核心线程数,任务4只能去阻塞队列排队了。
5.任务5进来,此时线程池已经有2个核心线程,达到预设的核心线程数,任务5只能去阻塞队列排队了,但发现此时的阻塞队列也达到预设的阻塞队列数,此时线程池会去创建非核心线程3出来执行任务5。
6.任务6进来,此时线程池里有2个核心线程和1个非核心线程,3个线程数已经达到预设的最大线程数了,并且3个线程都已经有未执行完成的任务,分别是任务1、任务2和任务5,并且阻塞队列也已经排满了任务,分别是任务3和任务4,那么任务6就只有被拒绝了,拒绝策略里的日志打印也便执行了。
7.后面的任务7、8、9、10都是一样的,线程池满了,阻塞队列也满了,只有被拒绝了。