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