- package cn.gaialine.threadpool;
- import java.util.concurrent.ArrayBlockingQueue;
- import java.util.concurrent.BlockingQueue;
- import java.util.concurrent.ThreadPoolExecutor;
- import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
- import java.util.concurrent.TimeUnit;
- /**
- * 线程池测试用例
- * @author yangyong
- *
- */
- public class TestThreadPool {
- //线程池维护线程的最少数量
- private static final int COREPOOLSIZE = 2;
- //线程池维护线程的最大数量
- private static final int MAXINUMPOOLSIZE = 5;
- //线程池维护线程所允许的空闲时间
- private static final long KEEPALIVETIME = 4;
- //线程池维护线程所允许的空闲时间的单位
- private static final TimeUnit UNIT = TimeUnit.SECONDS;
- //线程池所使用的缓冲队列,这里队列大小为3
- private static final BlockingQueue<Runnable> WORKQUEUE = new ArrayBlockingQueue<Runnable>(3);
- //线程池对拒绝任务的处理策略:AbortPolicy为抛出异常;CallerRunsPolicy为重试添加当前的任务,他会自动重复调用execute()方法;DiscardOldestPolicy为抛弃旧的任务,DiscardPolicy为抛弃当前的任务
- private static final AbortPolicy HANDLER = new ThreadPoolExecutor.AbortPolicy();
- public static void main(String[] args) {
- // TODO 初始化线程池
- ThreadPoolExecutor threadPool = new ThreadPoolExecutor(COREPOOLSIZE, MAXINUMPOOLSIZE, KEEPALIVETIME, UNIT, WORKQUEUE, HANDLER);
- for (int i = 1; i < 11; i++) {
- String task = "task@"+i;
- System.out.println("put->"+task);
-
如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。也就是:处理任务的优先级为:
当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数
核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。 - threadPool.execute(new ThreadPoolTask(task));
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- threadPool.shutdown();//关闭主线程,但线程池会继续运行,直到所有任务执行完才会停止。若不调用该方法线程池会一直保持下去,以便随时添加新的任务
- }
- }
- package cn.gaialine.threadpool;
- import java.io.Serializable;
- /**
- * 任务task
- * @author yangyong
- *
- */
- public class ThreadPoolTask implements Runnable,Serializable{
- private static final long serialVersionUID = -8568367025140842876L;
- private Object threadPoolTaskData;
- private static int produceTaskSleepTime = 10000;
- public ThreadPoolTask(Object threadPoolTaskData) {
- super();
- this.threadPoolTaskData = threadPoolTaskData;
- }
- public void run() {
- // TODO Auto-generated method stub
- System.out.println("start..."+threadPoolTaskData);
- try {
- //模拟线程正在执行任务
- Thread.sleep(produceTaskSleepTime);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- System.out.println("stop..."+threadPoolTaskData);
- threadPoolTaskData = null;
- }
- public Object getTask(){
- return this.threadPoolTaskData;
- }
- }
执行测试,每1秒添加一个任务,每个任务执行10秒,查看打印数据
- put->task@1
- start...task@1
- put->task@2
- start...task@2
- put->task@3
- put->task@4
- put->task@5
- put->task@6
- start...task@6
- put->task@7
- start...task@7
- put->task@8
- start...task@8
- put->task@9
- Exception in thread "main" java.util.concurrent.RejectedExecutionException
- at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(Unknown Source)
- at java.util.concurrent.ThreadPoolExecutor.reject(Unknown Source)
- at java.util.concurrent.ThreadPoolExecutor.execute(Unknown Source)
- at cn.gaialine.threadpool.TestThreadPool.main(TestThreadPool.java:42)
- stop...task@1
- start...task@3
- stop...task@2
- start...task@4
- stop...task@6
- start...task@5
- stop...task@7
- stop...task@8
- stop...task@3
- stop...task@4
- stop...task@5
- // 固定工作线程数量的线程池
- ExecutorService executorService1 = Executors.newFixedThreadPool(3);
- // 一个可缓存的线程池
- ExecutorService executorService2 = Executors.newCachedThreadPool();
- // 单线程化的Executor
- ExecutorService executorService3 = Executors.newSingleThreadExecutor();
- // 支持定时的以及周期性的任务执行
- ExecutorService executorService4 = Executors.newScheduledThreadPool(3);