什么是Java线程池RejectedExecutionHandler中传递的可运行对象

我有这样的thread pool with a RejectedExecutionHandler和一个Runnable任务.

sExecutorService = new ThreadPoolExecutor( ...    new MyRejectionHandler() );

interface MyTask extends Runnable { ... }

class MyTaskImpl implements MyTask { ...}     

我执行这样的任务

   sExecutorService.submit(myTask);        

在被拒绝的执行案例中,我希望得到被拒绝的Runnable(即MyTask),并在其中设置一些字段,将其标记为已拒绝.但我无法将其投射到MyTask.
那么runnable究竟是什么通过了被拒绝的执行?它似乎不是我提交的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.你可以调用execute not submit:

sExecutorService.execute(yourTask);

我认为没有办法从FutureTask获得你的任务.你只能为它调用run.所以如果你想调用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并重新定义newTaskFor方法,该方法负责Runnable到FutureTask包装:

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 – CommonPool中的ParallelStream队列任务,而不是自定义池