主要的是回调应该在PARENT线程上,而不是从任务调用,这就完成了工作(例如,不像ThreadPoolExecutor的afterExecute()钩子)。 我希望有类似的东西:
ExecutorService exec = Executors.newSingleThreadExecutor();
>>>>> exec.addAllJobsFinishedListener(someListener) <<<<<
exec.submit(task);
和someListener有一个Overrideable方法,如allJobsFinished()
答案 0 :(得分:2)
启动多个线程并在所有子节点完成后在父线程上运行回调的非阻塞方法
如果你想在PARENT线程上进行回调,那么我担心你需要让父线程调用exec.awaitTermination(...)
。提交完所有作业并调用exec.shutdown()
后,将等待线程池中的所有作业完成。如果你想要这个是非阻塞的,那么你将不得不在另一个线程中执行此操作(当然在另一个池中运行)。
我看不出它是如何在 非阻塞的父线程上运行的“监听器”。您可以进行后台线程检查,当AtomicBoolean
完成时,会将某种共享状态(如true
)更新为exec.awaitTermination(...)
。
ThreadPoolExecutor
确实有terminate()
方法可以覆盖。这不是你想要的吗?以下是该方法的javadocs。您的代码看起来像:
ThreadPoolExecutor threadPool =
new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()) {
public void terminated() {
super.terminated();
// do something magic
}
};
threadPool.execute(task);
// ...
// need to shutdown the pool after you've submitted all of the tasks
threadPool.shutdown();
如果“魔法”代码设置了主线程可以检查的共享volatile boolean
或AtomicBoolean
,那么它应该可以正常工作。
答案 1 :(得分:1)
看起来ThreadPoolExecutor
类对你来说是个不错的选择,你可以调用getActiveCount()
方法检查运行的线程而不被阻塞。 Also look on this article例如基于shutdown()
和isTerminated()
,这对我来说非常简单和漂亮。
此解决方案未涉及的是等待周期。某种睡眠应该处理这个问题。可能Condition
和Lock
的标准组合(查找POSIX条件变量示例)也是可接受的解决方案,但它缺乏先前方法的美感。
寻找这个,我认为它适合你:
package com.journaldev.threadpool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SimpleThreadPool {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread('' + i);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
// Put other work or calls here...
}
System.out.println('Finished all threads');
}
}
请注意以下事实:
executor.shutdown()
只会阻止新线程产生。executor.isTerminated()
不会阻止您。你可以自由地做其他工作。