Search code examples
groovyconcurrencyterminateexecutorservice

Groovy concurrency executor awaiting termination like join method in threads


i tried this with pool.shutdown() and pool.awaitTermination(0, TimeUnit.SECONDS) but it doesnt really want to wait for the tasks to be done before it prints me that it has finished. What am i doing wrong. BTW: The pool itself is the best thing i saw for multitasking till today. Glad i've found it here!!! The solution with signals like CountDownLatch doesnt seem to be the grooviest way... I am searching more for something like the join method as it is implemented for Threads.

import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger
import groovy.transform.Synchronized
import java.util.concurrent.*


class myThread extends Thread{
Integer timer=0
Integer count=0
String tn=''
String status=''

    def counter = new AtomicInteger()

    def void run() {
        println tn+' started ---- !!! ----'
        status='running'
        for( i in 1..count ) {
            sleep timer
            println tn+" Doing something loop $i"
            counter.incrementAndGet()
        }
        println tn+' finished - ### -'
        status='ok'
        this.join()
    }

}

def queue=[]

def mt1=new myThread(timer:550,count:10,tn:'t1',status:'')
def mt2=new myThread(timer:530,count:6,tn:'t2',status:'')
def mt3=new myThread(timer:550,count:10,tn:'t3',status:'')
def mt4=new myThread(timer:500,count:6,tn:'t4',status:'')

queue.push(mt1)
queue.push(mt2)
queue.push(mt3)
queue.push(mt4)


def maxConcurrent=2
def pool = Executors.newFixedThreadPool(maxConcurrent)
queue.each(){
    pool.submit(it)
}

pool.shutdown()
pool.awaitTermination(0, TimeUnit.SECONDS);

// HOW DO I WAIT HERE???

println 'NOW its REALLY!!! finished!'

Solution

  • Try using an ExecutorCompletionService

       def pool = Executors.newFixedThreadPool(maxConcurrent)
    
       def ecs = new ExecutorCompletionService<Void>(pool);
    
       queue.each {
           ecs.submit(it, Void); // I think this is how to handle a void return
       }
    
       // take blocks until task finished so get probably not needed in this case
       queue.each {
           ecs.take().get();
       }
    
       pool.shutdown()