I have thread pool, which will take Callable
worker thread with a RejectionHandler
. I need to get this Callable task in RejectionHandler
In your code
workers[i] = new CallableWorkerThread(random.nextInt(100));
FutureTask<Integer> task = new FutureTask<Integer>(workers[i]);
executor.submit(task);
you create a FutureTask
which wraps the CallableWorkerThread
instance but then you are using submit
which accepts an arbitrary Runnable
and returns a FutureTask
which wraps the Runnable
.
In other words, you are wrapping your FutureTask
in another FutureTask
. There are two ways to solve this
Use
workers[i] = new CallableWorkerThread(random.nextInt(100));
executor.submit(workers[i]);
to let the ExecutorService
wrap your Callable
inside a FutureTask
.
Use
workers[i] = new CallableWorkerThread(random.nextInt(100));
executor.execute(new FutureTask<Integer>(workers[i]));
to wrap the Callable
manually and enqueue it as Runnable
without further wrapping (note the use of execute
rather than submit
)
Since you want to enable retrieval of the original Callable
, the second option is for you, as it gives you full control over the FutureTask
instance:
static class MyFutureTask<T> extends FutureTask<T> {
final Callable<T> theCallable;
public MyFutureTask(Callable<T> callable) {
super(callable);
theCallable=callable;
}
}
submitting code:
for (int i=0; i< workers.length; i++){
workers[i] = new CallableWorkerThread(random.nextInt(100));
executor.execute(new MyFutureTask<Integer>(workers[i]));
}
RejectedExecutionHandler:
class RejectionHandlerImpl implements RejectedExecutionHandler{
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
if(r instanceof MyFutureTask) {
MyFutureTask<?> myFutureTask = (MyFutureTask)r;
Callable<?> c=myFutureTask.theCallable;
System.out.println(c);
}
else System.out.println(r);
}
}