我正在使用ThreadPoolTaskExecutor来执行我的任务,这是Callable接口的实现。我只想检查任务是否仍在池中(监控)。怎么做?我知道我可以从ThreadPoolExecutor获取队列但是如何将Runnable转换为Callable?
基本上我有这个可赎回的
public interface IFormatter extends Callable<Integer>{
Long getOrderId();
}
我正在执行它
ThreadPoolExecutor.submit(new Formatter(order));
最后我想在一些异步方法中遍历ExecutorService的队列,并检查带有orderId的线程是否仍在那里。
答案 0 :(得分:3)
正如this answer中所述,您可以通过手动创建FutureTask
并通过Callable
进行排名来控制execute
包裹submit
。否则,Callable
会将您的ExecutorService
包装到特定于Callable
的对象中,并将其放入队列中,从而无法通过标准API查询FutureTask
的属性。< / p>
使用自定义class MyFutureTask extends FutureTask<Integer> {
final IFormatter theCallable;
public MyFutureTask(IFormatter callable) {
super(callable);
theCallable=callable;
}
Long getOrderId() {
return theCallable.getOrderId();
}
}
threadPoolExecutor.execute(new MyFutureTask(new Formatter(order)));
通过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;
}
,
您可以在队列中查询订单ID:
ExecutorService
这适用于任何ThreadPoolExecutor
(假设它有一个队列)。如果您仅使用FutureTask
,则可以自定义其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);
}
}
实例的创建(从Java 6开始),而不是依赖提交者执行此操作:
MyThreadPoolExecutor
然后,使用ThreadPoolExecutor
而非IFormatter
的实例,每次提交MyFutureTask
实例时,都会使用FutureTask
而不是标准ExecutorService
自动换行。缺点是这仅适用于此特定[WordsUsed.index(word) for word in Phrase]
,并且泛型方法会为特殊处理生成未经检查的警告。
答案 1 :(得分:0)
由于您希望监视ExecutorService,请查看覆盖decorateTask()
。然后,您可以装饰未来以监控其状态。