2

我希望能够获得我已经submitted 到 ExecutorService(特别是 ThreadPoolExecutor)的 Callables,它们当前正在进行中(因此它们不能通过 获得getQueue())。

我尝试创建一个要覆盖的子类beforeExecute,但是给定的 Runnable 原来是 FutureTask,而不是提交的原始 Callable。

还有其他方法可以确定活动的可调用对象吗?


最终,我想用这些信息做两件事:

  1. 获取正在运行的任务,以便它们可以显示在用户界面中
  2. 检查Callable引用的文件是否匹配某个模式,如果是,取消它
4

2 回答 2

5

您可以覆盖AbstractExecutorService.newTaskFor(),它应该使您可以访问原始Runnables 和Callables。然后用你的跟踪装饰器装饰它们并传递给super.newTaskFor().

于 2012-09-13T21:18:42.633 回答
1

正如axtavt 所建议的,我创建了一个子类FutureTask

public class FutureCallable<V> extends FutureTask<V> {
    private Callable<V> callable;

    public FutureCallable(Callable<V> callable) {
        super(callable);
        this.callable = callable;
    }

    public Callable<V> getCallable() {
        return callable;
    }

}

并覆盖了我的ThreadPoolExecutor子类中的一些方法:

public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
    private Set<FutureCallable<UpdateResult>> running = new HashSet<FutureCallable<UpdateResult>>();

    @Override
    public <T> FutureCallable<T> newTaskFor(Callable<T> callable) {
        return new FutureCallable<T>(callable);
    }

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        FutureCallable<UpdateResult> task = (FutureCallable<UpdateResult>) r;
        running.add(task);
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        FutureCallable<UpdateResult> task = (FutureCallable<UpdateResult>) r;
        running.remove(task);
    }

    ...
}
于 2012-09-14T20:19:45.513 回答