• 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
  • 相关阅读:
    PL/SQL快捷键
    <c:if>条件判断 和 取值做乘法运算
    文档保存后找不到了误以为丢失,重做!
    Gson将参数放入实体类中进行包装之后再传递
    [leedcode 66] Plus One
    [leedcode 65] Valid Number
    [leedcode 64] Minimum Path Sum
    [leedcode 63] Unique Paths II
    [leedcode 62] Unique Paths
    [leedcode 61] Rotate List
  • 原文地址:https://www.cnblogs.com/hanfight/p/4678465.html
Copyright © 2020-2023  润新知