无法在RejectionHandler中获取CallableThread

我有线程池,它将带有RejectionHandler Callable工作线程。 我需要在RejectionHandler获取此Callable任务但无法获取它。

在下面的例子中,我需要执行RejectionHandler的可调用任务的uniqueId。 在RejecitonHandlerRunnable是一个FutureTask ,我希望它应该被转换为Callable worker thread。

请帮我在RejectionHandler中获取Callable Worker线程实例。

 import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.FutureTask; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class RejectionDemo { RejectionDemo(){ Random random = new Random(); ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, new ArrayBlockingQueue(2), new RejectionHandlerImpl()); CallableWorkerThread workers[] = new CallableWorkerThread[10]; for (int i=0; i< workers.length; i++){ workers[i] = new CallableWorkerThread(random.nextInt(100)); FutureTask task = new FutureTask(workers[i]); executor.submit(task); } } public static void main(String args[]){ RejectionDemo demo = new RejectionDemo(); } public class CallableWorkerThread implements Callable { private int uniqueId; CallableWorkerThread(int uniqueId) { this.uniqueId = uniqueId; } public Integer call() { System.out.println("Unique id="+uniqueId); return uniqueId; } public String toString(){ return ""+uniqueId; } } class RejectionHandlerImpl implements RejectedExecutionHandler{ public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { try{ System.out.println(r); }catch(Throwable t){ t.printStackTrace(); } } } } 

产量

 java.util.concurrent.FutureTask@70036428 Unique id=68 java.util.concurrent.FutureTask@6ea4b78b java.util.concurrent.FutureTask@e3f6d java.util.concurrent.FutureTask@1ce84763 java.util.concurrent.FutureTask@55a6c368 java.util.concurrent.FutureTask@4e77b794 java.util.concurrent.FutureTask@15b57dcb Unique id=55 Unique id=83 

我期待CallableWorkerThread而不是FutureTask。 帮我获取WorkerThread实例。

在你的代码中

 workers[i] = new CallableWorkerThread(random.nextInt(100)); FutureTask task = new FutureTask(workers[i]); executor.submit(task); 

你创建一个包装CallableWorkerThread实例的FutureTask ,然后你使用submit接受一个任意的Runnable并返回一个包装RunnableFutureTask

换句话说,您将FutureTask包装在另一个FutureTask 。 有两种方法可以解决这个问题

  1. 使用

     workers[i] = new CallableWorkerThread(random.nextInt(100)); executor.submit(workers[i]); 

    ExecutorService将你的Callable包装在FutureTask

  2. 使用

     workers[i] = new CallableWorkerThread(random.nextInt(100)); executor.execute(new FutureTask(workers[i])); 

    手动包装Callable并将其排入Runnable而不进一步包装(注意使用execute而不是submit

由于您希望启用原始Callable检索,因此第二个选项适合您,因为它可以让您完全控制FutureTask实例:

 static class MyFutureTask extends FutureTask { final Callable theCallable; public MyFutureTask(Callable callable) { super(callable); theCallable=callable; } } 

提交代码:

  for (int i=0; i< workers.length; i++){ workers[i] = new CallableWorkerThread(random.nextInt(100)); executor.execute(new MyFutureTask(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); } }