Use of ThreadPool - the Java Executors' based concurrent collection processor

Closures enhancements
{code}GParsExecutorsPool.withPool() {
    Closure longLastingCalculation = {calculate()}
    Closure fastCalculation = longLastingCalculation.async()  //create a new closure, which starts the original closure on a thread pool
    Future result=fastCalculation()                           //returns almost immediately
    //do stuff while calculation performs ...
    println result.get()
}
{code}

{code}
GParsExecutorsPool.withPool() {
    /**
     * The callAsync() method is an asynchronous variant of the default call() method to invoke a closure.
     * It will return a Future for the result value.
     */
    assert 6 == {it * 2}.call(3).get()
    assert 6 == {it * 2}.callAsync(3).get()
}
{code}

Executor service enhancements
{code}GParsExecutorsPool.withPool {ExecutorService executorService ->
    executorService << {println 'Inside parallel task'}
}
{code}

Asynchronous function processing
{code}
GParsExecutorsPool.withPool {
    assert [10, 20] == AsyncInvokerUtil.doInParallel({calculateA()}, {calculateB()})         //waits for results
    assert [10, 20] == AsyncInvokerUtil.executeAsync({calculateA()}, {calculateB()})*.get()  //returns Futures instead and doesn't wait for results to be calculated
}
{code}
