覆盖 ThreadPoolExecutor afterExecute 方法 - 有什么缺点吗? [英] Overriding ThreadPoolExecutor afterExecute method - any cons?

查看:78
本文介绍了覆盖 ThreadPoolExecutor afterExecute 方法 - 有什么缺点吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

钩子方法的优点:

beforeExecute(Thread, Runnable)afterExecute(Runnable, Throwable)

beforeExecute(Thread, Runnable) 和 afterExecute(Runnable, Throwable) 方法在每个任务执行之前和之后调用.这些可用于操作执行环境;例如,重新初始化 ThreadLocals、收集统计信息或添加日志条目

beforeExecute(Thread, Runnable) and afterExecute(Runnable, Throwable) methods that are called before and after execution of each task. These can be used to manipulate the execution environment; for example, reinitializing ThreadLocals, gathering statistics, or adding log entries

我正在使用自定义 ThreadPoolExecutor 来处理未捕获的异常.我可以在 RunnableCallable 中添加 try{} catch{} 块,但假设您不能强制开发人员添加这些块在相关的 Runnable 和 Callable 任务中.

I am using Custom ThreadPoolExecutor to handle uncaught exceptions. I can add try{} catch{} blocks in Runnable and Callable but assume a scenario where you can't force developer to add these blocks in relevant Runnable and Callable tasks.

这个 CustomThreadPoolExecutor ,覆盖了 ThreadPoolExecutor 中的 afterExecute() 方法如下(我已经将变量 b 的值赋值为零来模拟算术异常.

This CustomThreadPoolExecutor , overrides afterExecute() method in ThreadPoolExecutor as below ( I have assigned variable b value to Zero to simulate arithmetic exception.

import java.util.concurrent.*;
import java.util.*;

class CustomThreadPoolExecutor extends ThreadPoolExecutor {

   public CustomThreadPoolExecutor() { 
       super(1,10,60,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(1000));
   }

   protected void afterExecute(Runnable r, Throwable t) {
     super.afterExecute(r, t);
     if (t == null && r instanceof Future<?>) {
       try {
         Object result = ((Future<?>) r).get();
         System.out.println(result);
       } catch (CancellationException ce) {
           t = ce;
       } catch (ExecutionException ee) {
           t = ee.getCause();
       } catch (InterruptedException ie) {
           Thread.currentThread().interrupt(); // ignore/reset
       }
     }
     if (t != null)
       t.printStackTrace();
   }
 }


public class CustomThreadPoolExecutorDemo{

    public static void main(String args[]){
        System.out.println("creating service");
        //ExecutorService service = Executors.newFixedThreadPool(10);
        CustomThreadPoolExecutor service = new CustomThreadPoolExecutor();
        service.submit(new Runnable(){
                 public void run(){
                    int a=4, b = 0;
                    System.out.println("a and b="+a+":"+b);
                    System.out.println("a/b:"+(a/b));
                    System.out.println("Thread Name in Runnable after divide by zero:"+Thread.currentThread().getName());
                 }
            });
        service.shutdown();
    }
}

由于 submit() 在框架中隐藏异常,所以我重写了 afterExecute() 方法来捕获异常.

Since submit() hides exception at framework, I have overridden afterExecute() method to catch Exception.

在这个方法中,我用下面的语句添加了阻塞调用

In this method, I added blocking call with below statement

 Object result = ((Future<?>) r).get();

目前我有 10 个线程,队列容量为 1000.假设我的 Runnable 需要 5 秒才能完成.

Currently I have 10 threads with queue capacity as 1000. Assume that my Runnable takes 5 seconds to complete.

通过覆盖 afterExecute() 方法,我是否会产生任何性能开销或这种方法的任何缺点?

By overriding afterExecute() method, am I incurring any performance overhead OR any cons with this approach?

推荐答案

不,您的阻塞调用不会带来开销,因为任务已经完成执行并且具有 status >= NORMAL正如你在 void runWorker(Worker w)

No, your blocking call wouldn't bring an overhead, because task is already completed its execution and has status >= NORMAL as you can see in void runWorker(Worker w)

beforeExecute(wt, task);
Throwable thrown = null;
try {
    task.run();
} catch (RuntimeException x) {
    thrown = x; throw x;
} catch (Error x) {
    thrown = x; throw x;
} catch (Throwable x) {
    thrown = x; throw new Error(x);
} finally {
    afterExecute(task, thrown);
}

这篇关于覆盖 ThreadPoolExecutor afterExecute 方法 - 有什么缺点吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆