complete() needs to be called once when ALL work to indicate the service should be started as done. One way you can achieve what you describe though is to use an AtomicInteger shared by all tasks that is initialized to the number of tasks that must be ran, every task decrements and when the count hits 0 calls, that task calls context.complete().