What is the runnable object passed in Java thread pool RejectedExecutionHandler

丶灬走出姿态 提交于 2020-05-08 09:29:01

问题


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       

回答1:


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();    


来源:https://stackoverflow.com/questions/10931396/what-is-the-runnable-object-passed-in-java-thread-pool-rejectedexecutionhandler

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!