Java 从ThreadPoolTaskExecutor获取可调用或将Runnable强制转换为可调用

Java 从ThreadPoolTaskExecutor获取可调用或将Runnable强制转换为可调用,java,multithreading,spring,threadpoolexecutor,Java,Multithreading,Spring,Threadpoolexecutor,我用它来执行我的任务,这些任务是接口的实现。我只想及时检查任务是否仍在池中(监视)。怎么做?我知道我可以从中获取队列,但如何将Runnable转换为Callable 基本上我有这个电话 public interface IFormatter extends Callable<Integer>{ Long getOrderId(); } 最后,我想以某种异步方法遍历ExecutorService的队列,并检查orderId为的线程是否仍然存在。既然您希望监视ExecutorS

我用它来执行我的任务,这些任务是接口的实现。我只想及时检查任务是否仍在池中(监视)。怎么做?我知道我可以从中获取队列,但如何将Runnable转换为Callable

基本上我有这个电话

public interface IFormatter extends Callable<Integer>{
    Long getOrderId();
}

最后,我想以某种异步方法遍历ExecutorService的队列,并检查orderId为的线程是否仍然存在。

既然您希望监视ExecutorService,请查看重写
decorateTask()
。然后,您可以装饰未来以监控其状态。

如中所述,您可以通过手动创建并通过
execute
排队来控制
FutureTask
包装
Callable
。否则,
submit
会将您的
Callable
包装到一个特定于
ExecutorService
的对象中,并将其放入队列,从而无法通过标准API查询
Callable
的属性

使用自定义
FutureTask

class MyFutureTask extends FutureTask<Integer> {
    final IFormatter theCallable;

    public MyFutureTask(IFormatter callable) {
        super(callable);
        theCallable=callable;
    }
    Long getOrderId() {
        return theCallable.getOrderId();
    }
}
这适用于任何
执行器服务
(假设它有一个队列)。如果您仅使用
ThreadPoolExecutor
,您可以自定义其
FutureTask
实例的创建(从Java 6开始),而不是依赖提交者执行:

public class MyThreadPoolExecutor extends ThreadPoolExecutor {

    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                                TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }
    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
        TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
            workQueue, threadFactory);
    }
    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
        TimeUnit unit, BlockingQueue<Runnable> workQueue,
        RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
            workQueue, handler);
    }
    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
        TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
        RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
            workQueue, threadFactory, handler);
    }

    @Override
    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        if(callable instanceof IFormatter)
            return (FutureTask<T>)new MyFutureTask((IFormatter)callable);
        return super.newTaskFor(callable);
    }
}
公共类MyThreadPoolExecutor扩展了ThreadPoolExecutor{
公共MyThreadPoolExecutor(int corePoolSize、int maximumPoolSize、long keepAliveTime、,
时间单位,阻塞队列(工作队列){
super(corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue);
}
公共MyThreadPoolExecutor(int corePoolSize、int maximumPoolSize、long keepAliveTime、,
时间单位,BlockingQueue工作队列,ThreadFactory ThreadFactory){
超级(corePoolSize、maximumPoolSize、keepAliveTime、unit、,
工作队列(线程工厂);
}
公共MyThreadPoolExecutor(int corePoolSize、int maximumPoolSize、long keepAliveTime、,
时间单位,阻塞队列工作队列,
RejectedExecutionHandler(处理程序){
超级(corePoolSize、maximumPoolSize、keepAliveTime、unit、,
工作队列、处理程序);
}
公共MyThreadPoolExecutor(int corePoolSize、int maximumPoolSize、long keepAliveTime、,
时间单位、BlockingQueue工作队列、ThreadFactory ThreadFactory、,
RejectedExecutionHandler(处理程序){
超级(corePoolSize、maximumPoolSize、keepAliveTime、unit、,
工作队列、线程工厂、处理程序);
}
@凌驾
受保护的RunnableFuture newTaskFor(可调用可调用){
if(IFormatter的可调用实例)
return(FutureTask)newmyfuturetask((IFormatter)可调用);
返回super.newTaskFor(可调用);
}
}

然后,使用
MyThreadPoolExecutor
的实例而不是
ThreadPoolExecutor
每次提交
IFormatter
实例时,都会使用
MyFutureTask
而不是标准的
FutureTask
自动包装。缺点是,这仅适用于此特定的
ExecutorService
,并且泛型方法会为特殊处理生成未经检查的警告。

您不能,因为这些
可运行的
实际上是包装原始
可调用的
未来任务
实例。要使原始的
可调用
可访问,您必须将
ExecutorService
生成的
未来任务
替换为手动创建的任务。与比较。我已更新了我的问题。您的解决方案是否可以调用getOrderId?方法
decoriteTask
是在
ScheduledThreadPoolExecutor
中定义的,而不是
ThreadPoolExecutor
AbstractExecutorService
的所有子类的一般解决方案是重写
newTaskFor
public static boolean isEnqueued(ThreadPoolExecutor e, Long id) {
    for(Object o: e.getQueue().toArray()) {
        if(o instanceof MyFutureTask && Objects.equals(((MyFutureTask)o).getOrderId(), id))
            return true;
    }
    return false;
}
public class MyThreadPoolExecutor extends ThreadPoolExecutor {

    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                                TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }
    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
        TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
            workQueue, threadFactory);
    }
    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
        TimeUnit unit, BlockingQueue<Runnable> workQueue,
        RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
            workQueue, handler);
    }
    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
        TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
        RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
            workQueue, threadFactory, handler);
    }

    @Override
    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        if(callable instanceof IFormatter)
            return (FutureTask<T>)new MyFutureTask((IFormatter)callable);
        return super.newTaskFor(callable);
    }
}