/**
* public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
corePoolSize - 池中所保存的线程数,包括空闲线程。
maximumPoolSize - 池中允许的最大线程数。
keepAliveTime - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
unit - keepAliveTime 参数的时间单位。
workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的 Runnable 任务。
handler - 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。
*
*
* 策略1直接提交
* 2无界队列
* 3有界队列
* 当调用 execute() 方法添加一个任务时,线程池会做如下判断:
a. 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;
b. 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列。
c. 如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还是要创建线程运行这个任务;
d. 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会抛出异常,告诉调用者“我不能再接受任务了”。
所有 BlockingQueue 都可用于传输和保持提交的任务。可以使用此队列与池大小进行交互:
如果运行的线程少于 corePoolSize,则 Executor 始终首选添加新的线程,而不进行排队。
如果运行的线程等于或多于 corePoolSize,则 Executor 始终首选将请求加入队列,而不添加新的线程。
如果无法将请求加入队列,则创建新的线程,除非创建此线程超出 maximumPoolSize,在这种情况下,任务将被拒绝。
被拒绝的任务
handler有四个选择: <根据自己的业务来选择>
1:ThreadPoolExecutor.AbortPolicy()
抛出java.util.concurrent.RejectedExecutionException异常
2:ThreadPoolExecutor.CallerRunsPolicy()
重试添加当前的任务,他会自动重复调用execute()方法
3:ThreadPoolExecutor.DiscardOldestPolicy()
抛弃旧的任务
4:ThreadPoolExecutor.DiscardPolicy()
抛弃当前的任务
*/
/**
* 核心线程数量,即初始化线程池的启动线程数量
*/
private static final int COREPOOLSIZE = 2;
/**
* 最大线程数量
*/
private static final int MAXIMUMPOOLSIZE = 4;
/**
* 线程的存活时间,即完成任务后多久可再使用
*/
private static final int KEEPALIVETIME = 300;
public static void main(String[] args) {
//直接提交 SynchronousQueue<Runnable>() 直接提交通常要求无界 maximumPoolSizes 以避免拒绝新提交的任务
//如果MAXIMUMPOOLSIZE为3 任务大于3时抛异常RejectedExecutionException
ThreadPoolExecutor executorSyn = new ThreadPoolExecutor(COREPOOLSIZE, MAXIMUMPOOLSIZE, KEEPALIVETIME, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
//无界队列 LinkedBlockingQueue(不会创建新的线程,只会产生COREPOOLSIZE个线程,MAXIMUMPOOLSIZE无用)
ThreadPoolExecutor executorLink = new ThreadPoolExecutor(COREPOOLSIZE, MAXIMUMPOOLSIZE, KEEPALIVETIME, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>());
//有界队列 ArrayBlockingQueue(线程不够时创建新的线程最大为MAXIMUMPOOLSIZE,当任务大于MAXIMUMPOOLSIZE+10时报错)
ThreadPoolExecutor executorArray = new ThreadPoolExecutor(COREPOOLSIZE, MAXIMUMPOOLSIZE, KEEPALIVETIME, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(10));
ThreadPoolExecutor executor = executorSyn;
for(int i=1;i<=5;i++){
MyTask myTask = new MyTask(i);
executor.execute(myTask);
//System.out.println("线程池中线程数目:"+executor.getPoolSize()+",队列中等待执行的任务数目:"+
// executor.getQueue().size()+",已执行玩别的任务数目:"+executor.getCompletedTaskCount());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
executor.shutdown();
}
}
class MyTask implements Runnable{
private int taskNum;
public MyTask(int num) {
this.taskNum = num;
}
public MyTask() {
super();
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"----task "+taskNum+"-------------正在执行");
try {
Thread.currentThread().sleep(40000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"----task "+taskNum+"执行完毕");
}
}
//创建一个线程池
//创建一个指定工作线程数量的线程池 只有两个线程 策略:无界队列 LinkedBlockingQueue
ExecutorService pool1 = Executors.newFixedThreadPool(2);
//创建一个可缓存的线程池 直接创建新的线程 策略:直接提交(SynchronousQueue,最大线程数量为Integer.MAX_VALUE)
ExecutorService pool2 = Executors.newCachedThreadPool();
//创建一个单线程化的Executor 只有一个线程 策略:无界队列 LinkedBlockingQueue
ExecutorService pool3 = Executors.newSingleThreadExecutor();