正如在解释这个答案,你可能会通过控制
FutureTask包裹的
Callable通过手动创建它,并通过排队
execute。否则,
submit将您包装
Callable到一个
ExecutorService特定的对象中并将其放入队列中,从而使得无法
Callable通过标准API
查询via的属性。
使用自定义
FutureTask
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)));,
您可以查询队列中的订单ID:
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;}
这适用于任何对象
ExecutorService(假设它有一个队列)。如果仅使用一个
ThreadPoolExecutor,则可以自定义
FutureTask实例的创建(从Java6开始),而不是依靠提交者来创建它:
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每次提交
IFormatter都会自动使用
MyFutureTask代替standard进行包装
FutureTask。缺点是,这仅适用于此特定
ExecutorService方法,而通用方法会针对特殊处理生成未经检查的警告。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)