无法在RejectionHandler中获取CallableThread
我有线程池,它将带有RejectionHandler
Callable
工作线程。 我需要在RejectionHandler
获取此Callable任务但无法获取它。
在下面的例子中,我需要执行RejectionHandler的可调用任务的uniqueId。 在RejecitonHandler
, Runnable
是一个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
并返回一个包装Runnable
的FutureTask
。
换句话说,您将FutureTask
包装在另一个FutureTask
。 有两种方法可以解决这个问题
-
使用
workers[i] = new CallableWorkerThread(random.nextInt(100)); executor.submit(workers[i]);
让
ExecutorService
将你的Callable
包装在FutureTask
。 -
使用
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); } }