• Java Executor框架


    java.util.concurrent 包中包含灵活的线程池实现,但是更重要的是,它包含用于管理实现 Runnable 的任务的执行的整个框架,该框架称为 Executor 框架。该框架基于生产者-消费者模式,提交任务的操作相当于生产者,执行任务的线程则是相当于消费者。其类图结构:

    ThreadPoolExecutor是可以扩展的,它提供了几个可以在子类中可扩展的方法:beforeExecute 、afterExecute、terminated。无论任务是从run中正常返回还是抛出一个异常,afterExecute都会被调用[如果任务在完成后带有一个Error,那么就不会调用afterExecute]。如果抛出一个RuntimeException,那么任务将不被执行,并且afterExecute也不会被调用。在线程池完成关闭时调用terminated,也就是在所有的任务都已经完成并且所有工作者线程也已经关闭后。

    public class JHThreadPoolExecutor extends ThreadPoolExecutor {
    
        // 记录每个线程执行任务开始时间
        private ThreadLocal<Long> start = new ThreadLocal<Long>();
        
        // 记录所有任务完成使用的时间
        private AtomicLong totals = new AtomicLong();
        
        // 记录线程池完成的任务数
        private AtomicInteger tasks = new AtomicInteger();
        
        public JHThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                BlockingQueue<Runnable> workQueue) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
        }
    
        public JHThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
        }
    
        public JHThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
        }
    
        public JHThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
        }
    
        /**
         * 每个线程在调用run方法之前调用该方法
         * */ 
        protected void beforeExecute(Thread t, Runnable r) {
            super.beforeExecute(t, r);
            start.set(System.currentTimeMillis());
        }
    
        /**
         * 每个线程在执行完run方法后调用该方法
         * */
        protected void afterExecute(Runnable r, Throwable t) {
            super.afterExecute(r, t);
            tasks.incrementAndGet();
            totals.addAndGet(System.currentTimeMillis() - start.get());
        }
    
        @Override
        protected void terminated() {
            super.terminated();
            System.out.println("[THREADPOOL]完成"+ tasks.get() +"个任务,平均耗时:" + totals.get() / tasks.get() + ".ms");
        }
    
    }
    
    
    
    public class Task implements Runnable {
    
        @Override
        public void run() {
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (Exception e) {
                System.err.println(e.getMessage());
            }
        }
    
    }
    
    
    
    public class Main {
    
        public static void main(String []args) {
            BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
            JHThreadPoolExecutor  executor = new JHThreadPoolExecutor(3, 5, 5, TimeUnit.MINUTES, queue);
            for(int i = 0 ; i < 5 ; ++i) {
                executor.submit(new Task());
            }
            executor.shutdown();
        }
        
    }

    上述结果输出:

    [THREADPOOL]完成5个任务,平均耗时:5001.ms
  • 相关阅读:
    Bootstrap 网页乱码
    西游记人物
    球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
    利用条件运算符的嵌套来完成此题:学习成绩> =90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。
    s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由用户控制。
    实现判断字符串的开头和结尾
    值类型和引用类型
    随机生成4位验证码
    实现 从1-36中随机产生6个不重复的中奖号码
    冒泡排序
  • 原文地址:https://www.cnblogs.com/hanfight/p/4678465.html
Copyright © 2020-2023  润新知