使用beforeExecute、afterExecute和terminated扩展ThreadPoolExecutor

1、无论任务是从run中正常返回,还是抛出一个异常而返回,afterExecute都会被调用。如果任务在完成后带有一个Error,那么就不会盗用afterExecute。

2、如果beforeExecute抛出一个RuntimeException,那么任务将不被执行,并且afterExecute也不会被调用。

3、在线程完成关闭操作时调用terminated,也就是在所有任务都已经完成并且所有工作者线程也已经关闭后。terminated可以用来释放Executor在其生命周期里分配的各种资源,此外还可以执行发送通知、记录日志或者手机finalize统计信息等操作。

4、代码示例如下:

/**
 * TimingThreadPool
 * <p/>
 * Thread pool extended with logging and timing
 *
 * @author Brian Goetz and Tim Peierls
 */
public class TimingThreadPool extends ThreadPoolExecutor {

    public TimingThreadPool() {
        super(1, 1, 0L, TimeUnit.SECONDS, null);
    }

    private final ThreadLocal<Long> startTime = new ThreadLocal<Long>();
    private final Logger log = Logger.getLogger("TimingThreadPool");
    private final AtomicLong numTasks = new AtomicLong();
    private final AtomicLong totalTime = new AtomicLong();

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        super.beforeExecute(t, r);
        log.fine(String.format("Thread %s: start %s", t, r));
        startTime.set(System.nanoTime());
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        try {
            long endTime = System.nanoTime();
            long taskTime = endTime - startTime.get();
            numTasks.incrementAndGet();
            totalTime.addAndGet(taskTime);
            log.fine(String.format("Thread %s: end %s, time=%dns",
                    t, r, taskTime));
        } finally {
            super.afterExecute(r, t);
        }
    }

    @Override
    protected void terminated() {
        try {
            log.info(String.format("Terminated: avg time=%dns",
                    totalTime.get() / numTasks.get()));
        } finally {
            super.terminated();
        }
    }
}

beforeExecute()和afterExecute()是ThreadPoolExecutor提供的两个钩子方法,可以用于在线程池中的线程执行任务之前和执行任务之后进行一些额外的处理。具体使用方法如下: 1. beforeExecute()方法 beforeExecute()方法会在线程池中的线程执行任务之前被调用。可以在该方法中进行一些额外的初始化工作,比如记录任务开始时间、设置线程的优先级等。beforeExecute()方法的签名如下: ``` protected void beforeExecute(Thread t, Runnable r) ``` 其中,t表示将要执行任务的线程,r表示将要执行的任务。 2. afterExecute()方法 afterExecute()方法会在线程池中的线程执行任务之后被调用。可以在该方法中进行一些额外的清理工作,比如记录任务结束时间、释放资源等。afterExecute()方法的签名如下: ``` protected void afterExecute(Runnable r, Throwable t) ``` 其中,r表示已经执行完的任务,t表示任务执行过程中发生的异常(如果有)。 3. 使用示例 下面是一个示例,演示如何在beforeExecute()方法和afterExecute()方法中记录任务的开始时间和结束时间: ```java public class MyThreadPoolExecutor extends ThreadPoolExecutor { public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } @Override protected void beforeExecute(Thread t, Runnable r) { super.beforeExecute(t, r); System.out.println("Task " + r.toString() + " is starting at " + new Date()); } @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); System.out.println("Task " + r.toString() + " is finished at " + new Date()); } } ``` 在上面的示例中,我们继承了ThreadPoolExecutor类,并重写了其中的beforeExecute()方法和afterExecute()方法,用于记录任务的开始时间和结束时间。可以根据具体的需求在这两个方法中添加其他的处理逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值