【发布时间】:2015-06-29 20:10:57
【问题描述】:
我正在使用 Java Executor 框架同时执行多个线程。我想在所有线程都执行完后做一些操作。我们在执行器框架中是否有任何侦听器或事件捕获机制
【问题讨论】:
标签: java listener threadpool threadpoolexecutor
我正在使用 Java Executor 框架同时执行多个线程。我想在所有线程都执行完后做一些操作。我们在执行器框架中是否有任何侦听器或事件捕获机制
【问题讨论】:
标签: java listener threadpool threadpoolexecutor
ThreadPoolExecutor 的 API 停靠点描述了一些可能对此有用的钩子:
挂钩方法
此类提供受保护的可覆盖 beforeExecute(java.lang.Thread, java.lang.Runnable) 和 afterExecute(java.lang.Runnable, java.lang.Throwable) 方法是 在执行每个任务之前和之后调用。这些可以用来 操纵执行环境;例如,重新初始化 ThreadLocals、收集统计信息或添加日志条目。 此外,可以重写方法 terminate() 以执行任何 Executor 完全完成后需要进行的特殊处理 终止。
如果钩子或回调方法抛出异常,内部工作线程可能会依次失败并突然终止。
见https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
【讨论】:
您可以考虑从ThreadPoolExecutor 转移到ScheduledThreadPoolExecutor。不同之处在于,对于您排队的所有任务,您将获得一个Future<T>。
这允许您检查您提交的任务的.isDone() 并采取相应措施。如果您需要使用您提交的结果的结果尤其有趣,因为您可以干净地执行.get(),而不会阻塞调用线程直到执行完成。
另一种选择可能是实现ThreadFactory,它会为join() 主线程生成一个额外的侦听器线程,并在完成时通知您。
【讨论】:
ScheduledThreadPoolExecutor 可能是最好/最干净的方法
A a = new A();
B b= new B();
FutureTask fa = new FutureTask (a);
FutureTask fb = new FutureTask (b);
ExecutorService es = Executors.newFixedThreadPool(2);
es.submit (fa);
es.submit(fb);
String getName = (String)a.get();
String getSurName = (String)b.get();
es.shutdown ();
***//Here all threads are executed and
//you can write any code which you want to execute after
//finishing all the threads.***
或其他解决方法。
……
您可以使用LocalThrad 类编写守护程序类并生成线程,它将充当您的侦听器。
在这种情况下,无论您想实现什么,都可以通过使用上述守护程序类来实现。
【讨论】: