一、jdk中ThreadPoolExecutor的构造函数如下:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
先对线程池的构造参数做个简单的解释便于理解:
corePoolSize:核心线程数。如果没有设置allowCoreThreadTimeOut参数,就是一直会存活在线程池中的线程数。
maximumPoolSize:线程池中允许的最大线程数。
keepAliveTime:当线程池中的线程数超过了corePoolSize,在被终止前空闲线程等待新任务的最大时间。
workQueue:保存将要被执行的任务。线程池中的线程数达到corePoolSize后才将新任务放到workQueue中,workQueue队列满了后,线程池再创建新的线程直到maximumPoolSize。
threadFactory:线程工厂,可以自己实现ThreadFactory接口进行定制。
RejectedExecutionHandler:线程池中的线程达到了maximumPoolSize后,即饱和后执行的拒绝策略,默认是AbortPolicy。
首先执行如下代码:
package com.concurrency.fundamental.applyingthreadpools;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author xiwam
* @Date 2018/12/12 16:38
* @Desc
*/
public class SaturationPolicy {
private final static int N_THREAD = 1;
private final static int N_QUEUE = 1;
private ThreadPoolExecutor executor;
public SaturationPolicy() {
executor = new ThreadPoolExecutor(N_THREAD, N_THREAD, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(N_QUEUE));
//将这里的CallerRunsPolicy()替换成对应的拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
}
public static void main(String[] args) {
SaturationPolicy saturationPolicy = new SaturationPolicy();
saturationPolicy.execute();
}
public void execute() {
try {
for (int i = 0;i < 10;i++) {
executor.execute(new Worker(i));
}
} catch (RejectedExecutionException e) {
executor.shutdown();
}finally {
executor.shutdown();
}
}
}
class Worker implements Runnable {
private int i;
public Worker(int i) {
this.i = i;
}
@Override
public void run() {
System.out.println(" task :" + i + " is running");
}
}
AbortPolicy会抛出RejectedExecutionException。对应的打印结果
task :0 is running
task :1 is running
DiscardPolicy会丢弃掉饱和后的任务。对应的打印结果
task :0 is running
task :1 is running
DiscardOldestPolicy会丢弃掉队列中最久的任务,然后把新的任务放到队列中去。对应的打印结果
task :0 is running
task :9 is running
CallerRunsPolicy会让正在线程池中运行的线程执行新来的任务。任务丢弃有两种情况:一种是线程池挂掉了,还有一种是任务过多,造成请求tcp超时,传输层数据传输超时,任务丢弃。对应的打印结果(某一次)
task :2 is running
task :3 is running
task :4 is running
task :5 is running
task :6 is running
task :7 is running
task :8 is running
task :9 is running
task :0 is running
task :1 is running