Using threads and AtomicInteger
From Groovy you can use all of the normal concurrency facilities in Java and combine them with threads and closures as necessary. E.g. a (slightly modified) atomic counter from a Groovy example here:
import java.util.concurrent.atomic.AtomicInteger def counter = new AtomicInteger() synchronized out(message) { println(message) } def th = Thread.start { for( i in 1..8 ) { sleep 30 out "thread loop $i" counter.incrementAndGet() } } for( j in 1..4 ) { sleep 50 out "main loop $j" counter.incrementAndGet() } th.join() assert counter.get() == 12
The output will be something like this:
thread loop 1 main loop 1 thread loop 2 thread loop 3 main loop 2 thread loop 4 thread loop 5 main loop 3 thread loop 6 main loop 4 thread loop 7 thread loop 8
Fibonacci with Executors
A Groovy script to naively calculate the Fibonacci series inspired by the example here.
Note: a version using memoizing will be much more efficient but this illustrates using Java's built-in concurrency primitives from Groovy.
import java.util.concurrent.* CUTOFF = 12 // not worth parallelizing for small n THREADS = 100 println "Calculating Fibonacci sequence in parallel..." serialFib = { n -> (n < 2) ? n : serialFib(n-1) + serialFib(n-2) } pool = Executors.newFixedThreadPool(THREADS) defer = { c -> pool.submit(c as Callable) } fib = { n -> if (n < CUTOFF) return serialFib(n) def left = defer{ fib(n-1) } def right = defer{ fib(n-2) } left.get() + right.get() } (8..16).each{ n -> println "n=$n => ${fib(n)}" } pool.shutdown()
Which produces this:
Calculating Fibonacci sequence in parallel... n=8 => 21 n=9 => 34 n=10 => 55 n=11 => 89 n=12 => 144 n=13 => 233 n=14 => 377 n=15 => 610 n=16 => 987
If you want to convince yourself that some threads are actually being created, replace the last each line with:
showThreads = { println Thread.allStackTraces.keySet().join('\n') }
(8..16).each{ n -> if (n == 14) showThreads(); println "n=$n => ${fib(n)}" }
which will add something like the following to your output:
Thread[Finalizer,8,system] Thread[Reference Handler,10,system] Thread[TimerQueue,5,system] Thread[pool-1-thread-2,5,main] Thread[Thread-3,6,main] Thread[Thread-2,6,main] Thread[pool-1-thread-3,5,main] Thread[AWT-Shutdown,5,main] Thread[Signal Dispatcher,9,system] Thread[Attach Listener,5,system] Thread[AWT-EventQueue-0,6,main] Thread[DestroyJavaVM,5,main] Thread[pool-1-thread-1,5,main] Thread[Java2D Disposer,10,system] Thread[pool-1-thread-5,5,main] Thread[pool-1-thread-6,5,main] Thread[pool-1-thread-4,5,main] Thread[AWT-Windows,6,main]
Fibonacci with Functional Java
If you wish to make use of the functionaljava (tested with 2.1.3) library (see the link to the original example), you could use a Groovy program such as this:
import fj.* import fj.control.parallel.Strategy import static fj.Function.curry as fcurry import static fj.P1.curry as pcurry import static fj.P1.fmap import static fj.control.parallel.Actor.actor import static fj.control.parallel.Promise.* import static fj.data.List.range import static java.util.concurrent.Executors.* CUTOFF = 12 // not worth parallelizing for small n START = 8 END = 16 THREADS = 4 pool = newFixedThreadPool(THREADS) su = Strategy.executorStrategy(pool) spi = Strategy.executorStrategy(pool) add = fcurry({ a, b -> a + b } as F2) nums = range(START, END + 1) println "Calculating Fibonacci sequence in parallel..." serialFib = { n -> n < 2 ? n : serialFib(n - 1) + serialFib(n - 2) } print = { results -> def n = START results.each{ println "n=${n++} => $it" } pool.shutdown() } as Effect calc = { n -> n < CUTOFF ? promise(su, P.p(serialFib(n))) : calc.f(n - 1).bind(join(su, pcurry(calc).f(n - 2)), add) } as F out = actor(su, print) join(su, fmap(sequence(su)).f(spi.parMapList(calc).f(nums))).to(out)











