I have thread pool with a RejectedExecutionHandler like this and a Runnable task.
sExecutorService = new ThreadPoolExecutor( ... new MyRejectionHandler() );
interface MyTask extends Runnable { ... }
class MyTaskImpl implements MyTask { ...}
i execute a task like this
sExecutorService.submit(myTask);
in rejectedExecution case i was hoping to get hold of rejected Runnable (ie MyTask) and set some field in it marking it as rejected. But i am not able to cast it to MyTask. So what exactly is the runnable passed t o rejectedExecution ? It appears not MyTask i submitted . And how can i get hold of the rejected task in 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
What is ThreadPool in Java? A thread pool reuses previously created threads to execute current tasks and offers a solution to the problem of thread cycle overhead and resource thrashing.
keepAliveTime - when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating. unit - the time unit for the keepAliveTime argument. workQueue - the queue to use for holding tasks before the are executed.
Remember: If corePoolSize or more threads are running, the executor prefers queuing the task than creating a new thread. If the queue is full and creating a new thread would exceed maximumPoolSize the submitted task is rejected by the executor.
The problem is when you submit task with submit method TreadPoolExecutor (actually AbstractExecutorService) wrap it to FutureTask. After that you receive FutureTask not your Runnable. You can call execute not submit:
sExecutorService.execute(yourTask);
I don't think there is a way to get your task from FutureTask. You can only call run for it. So if you want to call submit and you need to call run - just do not convert to MyTask:
FutureTask myTask = (FutureTask) runnable;
myTask.run();
Object result = myTask.get();
Other way if you want to access you MyTask object can be creating of MyFutureTask extends FutureTask, that will allow get your object:
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;
}
}
Also you need to extends ThreadPoolExecutor and redefine newTaskFor method that is responsible for Runnable to FutureTask wraping:
public class MyThreadPoolExecutor extends ThreadPoolExecutor {
@Override
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new MyFutureTask(task, value);
}
}
After that you can use MyThreadPoolExecutor as a ThreadPoolExecutor and in rejecting task processing:
MyFutureTask myFutureTask = (MyFutureTask) runnable;
MyTask myTask = (MyTask) myFutureTask.getMyTask();
// Now you can do what you want with you task:
myTask.doSomthing();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With