我有这样的thread pool with a RejectedExecutionHandler和一个Runnable任务。
sExecutorService = new ThreadPoolExecutor( ... new MyRejectionHandler() );
interface MyTask extends Runnable { ... }
class MyTaskImpl implements MyTask { ...}
我执行这样的任务
sExecutorService.submit(myTask);
在rejectedExecution的情况下,我希望获得被拒绝的Runnable(即MyTask)并在其中设置一些字段以将其标记为被拒绝。但是我无法将其强制转换为MyTask。
那么runnable到底传递给了rejectedExecution到底是什么?看来不是我提交的MyTask。以及如何在RejectedExecutionHandler中掌握被拒绝的任务。
public class MyRejectionHandler implements RejectedExecutionHandler{
public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor) {
MyTask myTask = (MyTask) runnable; // exception
myTask.doSomething();
}
java.lang.ClassCastException: java.util.concurrent.FutureTask cannot be cast to MyTask
最佳答案
问题是,当您使用提交方法TreadPoolExecutor(实际上是AbstractExecutorService)提交任务时,将其包装到FutureTask中。之后,您将收到FutureTask而不是Runnable。您可以调用执行不提交:
sExecutorService.execute(yourTask);
我认为没有办法从FutureTask中获取任务。您只能为此打电话。因此,如果您要调用Submit并需要调用run-只是不要转换为MyTask:
FutureTask myTask = (FutureTask) runnable;
myTask.run();
Object result = myTask.get();
如果您要访问MyTask对象,可以使用其他方法来创建MyFutureTask扩展FutureTask,这将允许获取您的对象:
public MyFutureTask<V> extends FutureTask<V> {
private Runnable myTask;
public MyFutureTask(Runnable runnable, V result) {
super(runnable, result);
this.myTask = runnable;
}
public Runnable getMyTask() {
return myTask;
}
}
另外,您还需要扩展ThreadPoolExecutor并重新定义负责Runnable的FutureTask包装的newTaskFor方法:
public class MyThreadPoolExecutor extends ThreadPoolExecutor {
@Override
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new MyFutureTask(task, value);
}
}
之后,您可以将MyThreadPoolExecutor用作ThreadPoolExecutor并拒绝任务处理:
MyFutureTask myFutureTask = (MyFutureTask) runnable;
MyTask myTask = (MyTask) myFutureTask.getMyTask();
// Now you can do what you want with you task:
myTask.doSomthing();
关于java - 什么是Java线程池RejectedExecutionHandler中传递的可运行对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10931396/