java多线程之ThreadPoolExecutor

2020-03-09  本文已影响0人  eliteTyc

《阿里巴巴java开发手册》中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程,这样一方面是线程的创建更加规范,可以合理控制开辟线程的数量;另一方面线程的细节管理交给线程池处理,优化了资源的开销。而线程池不允许使用Executors去创建,而要通过ThreadPoolExecutor方式,这一方面是由于jdk中Executor框架虽然提供了如newFixedThreadPool()、newSingleThreadExecutor()、newCachedThreadPool()等创建线程池的方法,但都有其局限性,不够灵活;另外由于前面几种方法内部也是通过ThreadPoolExecutor方式实现,使用ThreadPoolExecutor有助于大家明确线程池的运行规则,创建符合自己的业务场景需要的线程池,避免资源耗尽的风险。

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

参数讲解
corePoolSize:核心线程数,如果他们创建了,它们会一直存在于线程池中,直到线程池关闭

maximunPoolSize:线程池可创建的最大线程数(核心线程与辅线程总和),这个值必须大于corePoolSize的值,否则会抛IllegalArgumentException

keepAliveTime:辅线程的空闲等待时间,一个辅线程等待多少时间还没有任务给它处理,它就被销毁

unit:keepAliveTime的单位(天,小时,分钟,秒,毫秒等等)

workQueue:任务等待队列,如果需要处理的任务大于线程池中的线程数,未处理的任务会暂存在任务队列(ps:不一定会保存任务到队列,需要根据当前任务队列的类型来判断,后面详细讲解)

threadFactory:线程创建工厂,一般使用默认(Executors.defaultThreadFactory())即可,可以自定义

handler:拒接策略,如果线程池中线程都在处理任务,任务队列中保存的任务也达到最大值,不能再接收任务了,如何拒绝

重要参数详解

拒绝策略:RejectedExecutionHandler,配置当线程池超载时的反应,(线程池已满且待处理任务大于任务等待队列时做出的反应)

等待队列:workQueue可以分为 直接提交队列有界任务队列无界任务队列优先任务队

先新建一个Runnable任务,方便后面测试

class Printer implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"正在执行。");
    }
}

执行任务的过程监控

beforeExecute:任务执行之前调用

afterExecute:任务执行结果后调用

terminated:线程池关闭之后调用

ThreadPoolExecutor threadPoolExecutor = null;
try {
    threadPoolExecutor = new ThreadPoolExecutor(1, 2, 30,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy()
    ){
        @Override
        protected void beforeExecute(Thread t, Runnable r) {
            super.beforeExecute(t, r);
            System.out.println("线程:"+t.getName()+"--正在执行:优先级"+((Printer) r).getPriority());
        }

        @Override
        protected void afterExecute(Runnable r, Throwable t) {
            super.afterExecute(r, t);
            System.out.println("优先级"+((Printer) r).getPriority()+"--执行完成");
        }

        @Override
        protected void terminated() {
            super.terminated();
            System.out.println("线程池退出******");
        }
    };

    for (int i = 0; i < 30; i++) {
        threadPoolExecutor.execute(new Printer(i));
    }
} finally {
    //        关闭线程池
    threadPoolExecutor.shutdown();

}
上一篇 下一篇

猜你喜欢

热点阅读