Java ExecutorService: awaitTermination of all recursively created tasks

后端 未结 11 2120
太阳男子
太阳男子 2020-11-29 03:27

I use an ExecutorService to execute a task. This task can recursively create other tasks which are submitted to the same ExecutorService and those

11条回答
  •  粉色の甜心
    2020-11-29 03:54

    Wow, you guys are quick:)

    Thank you for all the suggestions. Futures don't easily integrate with my model because I don't know how many runnables are scheduled beforehand. So if I keep a parent task alive just to wait for it's recursive child tasks to finish I have a lot of garbage laying around.

    I solved my problem using the AtomicInteger suggestion. Essentially, I subclassed ThreadPoolExecutor and increment the counter on calls to execute() and decrement on calls to afterExecute(). When the counter gets 0 I call shutdown(). This seems to work for my problems, not sure if that's a generally good way to do that. Especially, I assume that you only use execute() to add Runnables.

    As a side node: I first tried to check in afterExecute() the number of Runnables in the queue and the number of workers that are active and shutdown when those are 0; but that didn't work because not all Runnables showed up in the queue and the getActiveCount() didn't do what I expected either.

    Anyhow, here's my solution: (if anybody finds serious problems with this, please let me know:)

    public class MyThreadPoolExecutor extends ThreadPoolExecutor {
    
        private final AtomicInteger executing = new AtomicInteger(0);
    
        public MyThreadPoolExecutor(int coorPoolSize, int maxPoolSize, long keepAliveTime,
            TimeUnit seconds, BlockingQueue queue) {
            super(coorPoolSize, maxPoolSize, keepAliveTime, seconds, queue);
        }
    
    
        @Override
        public void execute(Runnable command) {
            //intercepting beforeExecute is too late!
            //execute() is called in the parent thread before it terminates
            executing.incrementAndGet();
            super.execute(command);
        }
    
    
        @Override
        protected void afterExecute(Runnable r, Throwable t) {
            super.afterExecute(r, t);
            int count = executing.decrementAndGet();
            if(count == 0) {
                this.shutdown();
            }
        }
    
    }
    

提交回复
热议问题