简体   繁体   English

所有子节点完成后,启动多个线程并在父线程上运行callabck的非阻塞方法

[英]Non-blocking method to start several threads and run a callabck on the parent thread when all children have finished

The main thing is that the callback should be on the PARENT thread and not called from the task, which is finishing the job (eg NOT like ThreadPoolExecutor's afterExecute() hook). 主要的是回调应该在PARENT线程上而不是从任务调用,这就完成了工作(例如,不像ThreadPoolExecutor的afterExecute()钩子)。 I'd like to have something like: 我希望有类似的东西:

ExecutorService exec = Executors.newSingleThreadExecutor();
>>>>> exec.addAllJobsFinishedListener(someListener) <<<<<
exec.submit(task);

and someListener to have an Overrideable method like allJobsFinished() 和someListener有一个Overrideable方法,如allJobsFinished()

Non-blocking method to start several threads and run a callback on the parent thread when all children have finished 所有子节点完成后,启动多个线程并在父线程上运行回调的非阻塞方法

If you want the callback on PARENT thread, then I'm afraid you need to have the parent thread calling exec.awaitTermination(...) . 如果你想在PARENT线程上回调,那么我担心你需要让父线程调用exec.awaitTermination(...) After you have submitted all of the jobs and the exec.shutdown() has been called, this waits for the all of the jobs in the thread-pool to complete. 提交完所有作业并exec.shutdown() ,将等待线程池中的所有作业完成。 If you want this to be non-blocking then you are going to have to do this in another thread (running in a different pool of course). 如果你想要这个是非阻塞的,那么你将不得不在另一个线程中执行此操作(当然,在另一个池中运行)。

I don't see how it can be a "listener" running on the parent thread that is also non-blocking. 我不知道它是如何在父线程上运行的“监听器” 也是非阻塞的。 You could have a background thread checking which will update some sort of shared state (like an AtomicBoolean ) to be true when the exec.awaitTermination(...) completes. 您可以进行后台线程检查,当exec.awaitTermination(...)完成时,它将更新某种共享状态(如AtomicBoolean )为true

ThreadPoolExecutor does have terminate() method that you can override. ThreadPoolExecutor确实有你可以覆盖的terminate()方法。 Is that not what you want? 这不是你想要的吗? Here are the javadocs for the method. 以下是该方法的javadoc Your code would look something like: 您的代码看起来像:

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();

If the "something magic" code set a shared volatile boolean or an AtomicBoolean that the main thread could check, then it should work fine. 如果“魔法”代码设置了主线程可以检查的共享volatile booleanAtomicBoolean ,那么它应该可以正常工作。

Looks like ThreadPoolExecutor class is really good option for you and you can call getActiveCount() method to check for running threads without being blocked. 看起来ThreadPoolExecutor类对你来说是非常好的选择,你可以调用getActiveCount()方法来检查运行的线程而不被阻塞。 Also look on this article for example based on shutdown() and isTerminated() which is pretty simple and nice as for me. 另请 isTerminated() 本文 ,例如基于shutdown()isTerminated() ,这对我来说非常简单和好。

What this solution does not cover is waiting cycle. 这个解决方案没有涵盖的是等待周期。 Some kind of sleeping should handle this. 某种睡眠应该处理这个问题。 Probably standard combination of Condition and Lock (look for POSIX condition variable example) is also acceptable solution for this but it lacks beauty of previous approach. 可能是ConditionLock标准组合(寻找POSIX条件变量示例)也是可接受的解决方案,但它缺乏先前方法的美感。

Look for this, I think it is right for you: 寻找这个,我认为它适合你:

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');
    }
}

Please pay attention to the following facts: 请注意以下事实:

  • executor.shutdown() just blocks new threads spawning. executor.shutdown()只阻止生成的新线程。
  • executor.isTerminated() doesn't block you. executor.isTerminated()不会阻止你。 You are free to do other job. 你可以自由地做其他工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM