ThreadPoolTrhead线程池使用

1.首先定义一个自己的线程类


import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author muYou
 * @info 定制化并发线程池
 * @date 2019-07-30
 */
public class MyExecutor extends ThreadPoolExecutor {

    private ConcurrentHashMap<String,Date> startTime;

    /**
     *  @info  the method overrid father
     * @param corePoolSize
     * @param maximumPoolSize
     * @param keepAliveTime
     * @param unit
     * @param workQueue
     * @param threadFactory
     * @param handler
     */
    public MyExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                      TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
        startTime = new ConcurrentHashMap<>();
    }

    /**
     * 覆盖shutdown()方法。将关于已执行的任务,
     * 正在运行的任务和待处理的任务信息持久化。
     * 然后,使用super关键字调用父类的shutdown()方法。
     */
    @Override
    public void shutdown() {
        System.out.printf("threadPoolExecutor: Going to shutdown.\n");
        System.out.printf("threadPoolExecutor: 已执行的任务(Executed ):%d\n",getCompletedTaskCount());
        System.out.printf("threadPoolExecutor: 运行任务(Running ):%d\n",getActiveCount());
        System.out.printf("threadPoolExecutor: 挂起的任务(Pending ):%d\n",getQueue().size());

        super.shutdown();
    }

    /**
     * 覆盖shutdownNow()方法。将关于已执行的任务,
     * 正在运行的任务和待处理的任务信息持久化。
     * 然后,使用super关键字调用父类的shutdownNow()方法。
     * @return
     */
    @Override
    public List<Runnable> shutdownNow() {
        System.out.printf("threadPoolExecutor: 立即关闭.\n");
        System.out.printf("threadPoolExecutor: 已执行的任务(Executed ): %d\n",getCompletedTaskCount());
        System.out.printf("threadPoolExecutor: 运行任务(Running ): %d\n",getActiveCount());
        System.out.printf("threadPoolExecutor: 挂起的任务(Pending ): %d\n",getQueue().size());
        return super.shutdownNow();
    }

    /**
     * 覆盖beforeExecute()方法。写入一条信息
     * (将要执行任务的线程名和任务的哈希编码)到控制台。
     * 在Map中,使用这个任务的哈希编码作为key,存储开始日期。
     */
    @Override
    protected void beforeExecute(Thread t, Runnable r) {
            System.out.printf("threadPoolExecutor: A task is beginning: %s : %s\n",t.getName(),r.hashCode());
        startTime.put(String.valueOf(r.hashCode()), new Date());
        super.beforeExecute(t, r);
    }

    /**
     * 覆盖afterExecute()方法。将任务的结果和计算任务的运行时间
     * (将当前时间减去存储在HashMap中的任务的开始时间)
     * 的信息写入到控制台。
     * @param r
     * @param t
     */
    @Override
    protected void afterExecute(Runnable r, Throwable t) {

        Future<?> result = (Future<?>) r;
        System.out.println("==========================\n");
        System.out.printf("threadPoolExecutor: A task is finishing.\n");
        try {
            System.out.printf("threadPoolExecutor: Result: %s\n",result.get());
            Date startDate = startTime.remove(String.valueOf(r.hashCode()));
            Date finishDate = new Date();
            long diff=finishDate.getTime()-startDate.getTime();
            System.out.printf("threadPoolExecutor: 持续时间(Duration)ms: %d\n",diff);
            System.out.printf("*********************************\n");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }


        super.afterExecute(r, t);
    }


}

4.调用

// 线程池满了。继续往里面添加。
static RejectedExecutionHandler handler = new RejectedExecutionHandler() {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        if (!executor.isShutdown()){
            System.out.println("线程池已满");
            try {
                executor.getQueue().put(r);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
};


public void 实现类方法(){
    
    CountDownLatch cdl = new CountDownLatch(1);
    final Future<Boolean> submit = myExecutor.submit(new                 
    TaskResult(employeeId,companyId,cdl));
    final Boolean result = submit.get();
    //TODO 闭锁等待
    cdl.await();
}

/** 
 * 线程池内部类
 */
 class TaskResult implements Callable<Boolean> {
        private Long userId;
        private Long companyId;
        private CountDownLatch cdl;


        public TaskResult(Long userId,Long companyId,CountDownLatch cdl) {
            this.userId = userId;
            this.companyId = companyId;
            this.cdl = cdl;
        }
        @Override
        public Boolean call() {
            try {
                业务方法    
                return true;
            }catch (Exception e){
                log.error("执行线程池任务时异常{},{}",e,e.getMessage());
                e.printStackTrace();
            }finally {
                cdl.countDown();

            }
            return false;
        }
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值