Groovy and Concurrency Paul King

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    6 Favorites

    Groovy and Concurrency Paul King - Presentation Transcript

    1. Groovy and Concurrency Dr Paul King, ASERT: @paulk_asert
    2. Topics • Introduction • Parallelism Options – Processes – Threads – Libraries – Frameworks • gpars • Further Information 2
    3. INTRO 3 (c) ASERT 2009 SpringOne 2GX 2009. All rights reserved. Do not distribute without permission.
    4. What is Groovy? • “Groovy is like a super version of Java. It can leverage Java's enterprise capabilities but also has cool productivity features like closures, DSL support, builders and dynamic typing.” Groovy = Java – boiler plate code + optional dynamic typing + closures + domain specific languages + builders + metaprogramming SpringOne2GX - 4
    5. Groovy Goodies Overview • Fully object oriented • Closures: reusable and assignable pieces of code • Operators can be • GPath: efficient overloaded object navigation © ASERT 2006-2009 • Multimethods • GroovyBeans • Literal declaration for • grep and switch lists (arrays), maps, ranges and regular • Templates, builder, expressions swing, Ant, markup, XML, SQL, XML-RPC, Scriptom, Grails, tests, Mocks SpringOne2gx_Oct2009 - 5
    6. Growing Acceptance … Making Java Groovy (soon) Now free
    7. … Growing Acceptance … © ASERT 2006-2009 http://www.jroller.com/scolebourne/entry/devoxx_2008_whiteboard_vote http://www.java.net SpringOne2gx_Oct2009 - 7
    8. … Growing Acceptance … What alternative JVM language are you using or intending to use © ASERT 2006-2009 http://www.leonardoborges.com/writings SpringOne2gx_Oct2009 - 8
    9. … Growing Acceptance … © ASERT 2006-2009 http://it-republik.de/jaxenter/quickvote/results/1/poll/44 (translated using http://babelfish.yahoo.com) SpringOne2gx_Oct2009 - 9
    10. … Growing Acceptance © ASERT 2006-2009 SpringOne2gx_Oct2009 - 10
    11. Why Groovy? Technical Answer • Minimal learning curve • Compiles to bytecode • Java object model & integration • Annotations • "Optional" static typing • Both run-time and compile-time metaprogramming SpringOne2GX - 11
    12. Why Groovy? Adoption Assessment • Innovators/Thought leaders – Ideas, power, flexibility, novelty, thinking community • Early adopters – Productivity benefits and collegiate community – Leverage JVM and potential for mainstream • Mainstream – Leverage existing Java skills, low learning curve – Leverage JVM and production infrastructure – Professional community – Tools, tools, tools
    13. Source: Herb Sutter: http://www.gotw.ca/publications/concurrency-ddj.htm "Andy giveth and Bill taketh away" SpringOne2GX - 13
    14. Why is it hard? • Many issues to deal with: – Doing things in parallel, concurrently, asynchronously • Processes, Threads, Co-routines, Events, Scheduling – Sharing/Synchronization Mechanisms • shared memory, locks, transactions, wait/notify, STM, message passing, actors, serializability, persistence, immutability – Abstractions • Shared memory on top of messaging passing • Message passing on top of shared memory • Dataflow, Selective Communication, Continuations – Data Structures and Algorithms • Queues, Heaps, Trees • Sorting, Graph Algorithms SpringOne2GX - 14
    15. PARALLELISM OPTIONS 15 (c) ASERT 2009 SpringOne 2GX 2009. All rights reserved. Do not distribute without permission.
    16. Concurrent Programming in Groovy • Java concurrent programming goodness – Normal OO methods – Ability to have immutable types – Some concurrency building blocks • Process Enhancements – AntBuilder and GDK methods • Closures for greater flexibility – Enabler for concurrency – Closure is Runnable and Callable* • Third-party Java libraries – Functional Java (Actors) – Cascading.groovy subproject for Hadoop clusters – Jetlang, JPPF, GridGain, Google Collections, Gruple – Groovy actors: http://www.groovyactors.org * Kind of and maybe exactly soon SpringOne2GX - 16
    17. Java Concurrency Features • The early years – Threads, synchronised and non-synchronised collections, synchronisation at the language level, Monitors (wait/notify), Locks, ThreadLocal, final, ... • More recent enhancements – java.util.concurrent: Executors, Thread Pools, Optimistic updates, Blocking queues, Synchronizers, Callables, Futures, Atomic operations, Deques, ... • Emerging – Phasers, fork/join, TransferQueue, ... • Leverage related APIs/technologies – Networking, real-time, GUIs, simulation, database, multimedia, operating systems, parallel processing, distribution, mobile agents, nio, ... SpringOne2GX - 17
    18. Process Enhancements… • Using AntBuilder [echo] Message 6 [echo] Message 9 [echo] Message 8 def ant = new AntBuilder() [echo] Message 0 ant.parallel { [echo] Message 2 10.times { echo "Message $it" } [echo] Message 4 } [echo] Message 1 [echo] Message 7 [echo] Message 5 [echo] Message 3 SpringOne2GX - 18
    19. Process Enhancements… • Using AntBuilder (Cont’d) def ant = new AntBuilder() ant.taskdef(name:'groovy', classname:'org.codehaus.groovy.ant.Groovy') ant.parallel { 10.times { echo "Ant message $it" groovy "println 'Groovy via ant message $it'" println "Groovy message $it" // or fork java, command line, thread ... } } def ant = new AntBuilder() ant.exec(outputproperty:"cmdOut", errorproperty: "cmdErr", resultproperty:"cmdExit", failonerror: "true", executable: /opt/myExecutable') { arg(line:'*"first with space"* second') } SpringOne2GX - 19
    20. …Process Enhancements… • Thread improvements Thread.start{ sleep(1001); println 'one' } Thread.start{ sleep(1000); println 'two' } println 'one' def t = Thread.start{ sleep(100); println 'three' } println 'two' t.join() println 'four' SpringOne2GX - 20
    21. …Process Enhancements… • Thread improvements (Cont’d) class Storage { List stack = [] synchronized void leftShift(value){ stack << value println "push: $value" notifyAll() } synchronized Object pop() { while (!stack) { try{ wait() } catch(InterruptedException e){} } def value = stack.pop() println "pop : $value" return value } } ... SpringOne2GX - 21
    22. …Process Enhancements… • Thread improvements (Cont’d) push: 0 push: 1 ... push: 2 storage = new Storage() pop : 2 push: 3 Thread.start { push: 4 for (i in 0..9) { pop : 4 storage << i push: 5 sleep 100 push: 6 } pop : 6 } push: 7 push: 8 Thread.start { pop : 8 10.times { push: 9 sleep 200 pop : 9 storage.pop() pop : 7 } pop : 5 } pop : 3 pop : 1 pop : 0 SpringOne2GX - 22
    23. …Process Enhancements… • Thread improvements (Cont’d) ROCK! . 25 import java.util.concurrent.locks.ReentrantLock . 33 import static System.currentTimeMillis as now . 34 def startTime = now() . 35 ReentrantLock.metaClass.withLock = { critical -> . 36 lock() .. 131 try { critical() } .. 134 finally { unlock() } } .. 137 def lock = new ReentrantLock() .. 138 def worker = { threadNum -> .. 139 4.times { count -> ... 232 lock.withLock { ... 234 print " " * threadNum ... 237 print "." * (count + 1) ... 238 println " ${now() - startTime}" ... 239 } Thread.sleep 100 .... 334 } .... 336 } .... 337 5.times { Thread.start worker.curry(it) } .... 338 println "ROCK!" .... 339 Source: http://chrisbroadfoot.id.au/articles/2008/08/06/groovy-threads SpringOne2GX - 23
    24. … Process Enhancements… • Thread Management meets AtomicInteger import java.util.concurrent.atomic.AtomicInteger def counter = new AtomicInteger() synchronized out(message) { println(message) thread loop 1 } main loop 1 def th = Thread.start { thread loop 2 for( i in 1..8 ) { thread loop 3 sleep 30 main loop 2 out "thread loop $i" thread loop 4 counter.incrementAndGet() } thread loop 5 } main loop 3 for( j in 1..4 ) { thread loop 6 sleep 50 main loop 4 out "main loop $j" thread loop 7 counter.incrementAndGet() thread loop 8 } th.join() assert counter.get() == 12 SpringOne2GX - 24
    25. …Process Enhancements • Process Management proc1 = 'ls'.execute() def process = "ls -l".execute() proc2 = 'tr -d o'.execute() println "Found text ${process.text}" proc3 = 'tr -d e'.execute() proc4 = 'tr -d i'.execute() proc1 | proc2 | proc3 | proc4 def process = "ls -l".execute() proc4.waitFor() process.in.eachLine { line -> if (proc4.exitValue()) println line } print proc4.err.text def sout = new StringBuffer() else def serr = new StringBuffer() print proc4.text proc1 = 'gzip -c'.execute() proc2 = 'gunzip -c'.execute() proc2.consumeProcessOutput(sout, serr) proc1 | proc2 proc1.consumeProcessErrorStream(serr) proc1.withWriter { writer -> writer << 'test text' } proc2.waitForOrKill(1000) println 'sout: ' + sout // => test text println 'serr: ' + serr SpringOne2GX - 25
    26. Lightweight threads: Jetlang • Jetlang – A high performance java threading library Fiber receiver = new ThreadFiber(); // JAVA receiver.start(); // create java.util.concurrent.CountDownLatch to notify when message arrives final CountDownLatch latch = new CountDownLatch(1); // create channel to message between threads Channel<String> channel = new MemoryChannel<String>(); Callback<String> onMsg = new Callback<String>() { public void onMessage(String message) { //open latch latch.countDown(); } }; //add subscription for message on receiver thread channel.subscribe(receiver, onMsg); //publish message to receive thread. the publish method is thread safe. channel.publish("Hello"); //wait for receiving thread to receive message latch.await(10, TimeUnit.SECONDS); //shutdown thread receiver.dispose(); SpringOne2GX - 26
    27. Immutability options • Built-in def animals = ['cat', 'dog', 'horse'].asImmutable() animals << 'fish' // => java.lang.UnsupportedOperationException • Google Collections – Numerous improved immutable collection types import com.google.common.collect.* List<String> animals = ImmutableList.of("cat", "dog", "horse") animals << 'fish' // => java.lang.UnsupportedOperationException • Groovy run-time metaprogramming def animals = ['cat', 'dog', 'horse'] ArrayList.metaClass.leftShift = { throw new UnsupportedOperationException() } animals << 'fish' // => java.lang.UnsupportedOperationException • Groovy 1.6 compile-time metaprogramming – @Immutable can help us create such classes SpringOne2GX - 27
    28. Better Design Patterns: Immutable... • Java Immutable Class – As per Joshua Bloch // ... @Override Effective Java public boolean equals(Object obj) { if (this == obj) public final class Punter { return true; private final String first; if (obj == null) private final String last; return false; if (getClass() != obj.getClass()) public String getFirst() { return false; return first; Punter other = (Punter) obj; } if (first == null) { if (other.first != null) public String getLast() { return false; return last; } else if (!first.equals(other.first)) } return false; if (last == null) { @Override if (other.last != null) public int hashCode() { return false; final int prime = 31; } else if (!last.equals(other.last)) int result = 1; return false; result = prime * result + ((first == null) return true; ? 0 : first.hashCode()); } result = prime * result + ((last == null) ? 0 : last.hashCode()); @Override return result; public String toString() { } return "Punter(first:" + first + ", last:" + last + ")"; public Punter(String first, String last) { } this.first = first; this.last = last; } } // ... SpringOne2GX - 28
    29. ...Better Design Patterns: Immutable... • Java Immutable Class But in Groovy we try to reduce boilerplate code. – As per Joshua Bloch // ... @Override Effective Java public boolean equals(Object obj) { if (this == obj) public final class Punter { return true; private final String first; if (obj == null) private final String last; return false; if (getClass() != obj.getClass()) public String getFirst() { return false; return first; Punter other = (Punter) obj; } if (first == null) { if (other.first != null) public String getLast() { return false; return last; } else if (!first.equals(other.first)) } return false; if (last == null) { @Override if (other.last != null) public int hashCode() { return false; final int prime = 31; } else if (!last.equals(other.last)) int result = 1; return false; result = prime * result + ((first == null) return true; ? 0 : first.hashCode()); } result = prime * result + ((last == null) ? 0 : last.hashCode()); @Override return result; public String toString() { } return "Punter(first:" + first + ", last:" + last + ")"; public Punter(String first, String last) { } this.first = first; this.last = last; } } // ... SpringOne2GX - 29
    30. ...Better Design Patterns: Immutable Thanks to compile-time metaprogramming. @Immutable class Punter { String first, last } SpringOne2GX - 30
    31. Parallelize your arrays with JSR 166y //Create a pool with size close to the number of processor cores def pool = new ForkJoinPool(2) def createParallelArray(pool, collection) { return ParallelArray.createFromCopy( collection.toArray(new Object[collection.size()]), pool) } // Enhance ArrayLists to find matching objects in parallel ArrayList.metaClass.findAll = {Closure cl -> createParallelArray(pool, delegate). withFilter({cl(it)} as Predicate).all().asList() } def sites=['http://www.jroller.com', 'http://www.infoq.com', 'http://java.dzone.com'] def groovySites = sites.findAll { new URL(it).text.toLowerCase().contains('groovy')} println "These sites talk about Groovy today: ${groovySites}" Source: http://www.jroller.com/vaclav/date/20080923 SpringOne2GX - 31
    32. Fibonacci Case Study SpringOne2GX - 32
    33. Fibonacci… START = 8 Serial END = 16 version fib = {n -> n < 2 ? n : fib(n - 1) + fib(n - 2) } (START..END).each {num -> println "n:$num => ${fib(num)}" } SpringOne2GX - 33
    34. …Fibonacci… import java.util.concurrent.* ConcurrentHashMap THREADS = 4 version START = 8 END = 16 QUIT = -1 class Fibonacci { def values = new ConcurrentHashMap() int calc(x) { x < 2 ? x : calc(x-1) + calc(x-2) } int calcWithCache(x) { def result = values[x] if (!result) { result = calc(x) values.putIfAbsent(x, result) } result } } println "Calculating Fibonacci sequence in parallel..." def queue = new ArrayBlockingQueue(10) SpringOne2GX - 34
    35. …Fibonacci… Thread.start('Producer') { int x = START while (x <= END) { sleep 200 queue << x++ } sleep 1000 THREADS.times { queue << QUIT } } (1..THREADS).each { def name = "Consumer$it" Thread.start(name) { def done = false def fib = new Fibonacci() while (!done) { def n = queue.take() if (n == QUIT) done = true else println "$name n:$n => ${fib.calcWithCache(n)}" } } } SpringOne2GX - 35
    36. …Fibonacci… Executor import java.util.concurrent.* version 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() SpringOne2GX - 36
    37. …Fibonacci… import EDU.oswego.cs.dl.util.concurrent.FJTask import EDU.oswego.cs.dl.util.concurrent.FJTaskRunnerGroup class Fib extends FJTask { static final CUTOFF = 12 Fork/Join volatile int number version int getAnswer() { if (!isDone()) throw new IllegalStateException() number } void run() { int n = number if (n <= CUTOFF) number = seqFib(n) else { def f1 = new Fib(number: n - 1) def f2 = new Fib(number: n - 2) coInvoke(f1, f2) number = f1.number + f2.number } } int seqFib(int n) { n < 2 ? n : seqFib(n - 1) + seqFib(n - 2) } } SpringOne2GX - 37
    38. …Fibonacci… def THREADS = 2 def group = new FJTaskRunnerGroup(THREADS) def START = 8 def END = 16 (START..END).each {num -> def f = new Fib(number: num) group.invoke(f) println "n:$num => $f.answer" } SpringOne2GX - 38
    39. …Fibonacci… import fj.* import fj.control.parallel.Strategy FunctionalJava import static fj.Function.curry as fcurry version 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..." SpringOne2GX - 39
    40. …Fibonacci… 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) SpringOne2GX - 40
    41. …Fibonacci… import org.jetlang.core.Callback import org.jetlang.channels.MemoryChannel Jetlang import org.jetlang.fibers.ThreadFiber version import java.util.concurrent.* println "Calculating Fibonacci sequence with two cooperating fibers..." class FibonacciCalc implements Callback { private channel, receiver def limit, name, latch void onMessage(inpair) { def next = inpair[0] + inpair[1] def outpair = [inpair[1], next] println "$name next:$next" channel.publish(outpair) if (next > limit) { latch.countDown() sleep 200 receiver.dispose() } } // ... SpringOne2GX - 41
    42. …Fibonacci // ... void subscribe(other) { channel.subscribe(receiver, other) } FibonacciCalc() { channel = new MemoryChannel() receiver = new ThreadFiber() receiver.start() } } def seed = [0, 1] def latch = new CountDownLatch(2) def calcA = new FibonacciCalc(limit: 500, name: 'CalcA', latch: latch) def calcB = new FibonacciCalc(limit: 500, name: 'CalcB', latch: latch) calcA.subscribe calcB calcB.subscribe calcA calcA.onMessage seed latch.await(10, TimeUnit.SECONDS) SpringOne2GX - 42
    43. Other High-Level Libraries: JPPF – Open source Grid Computing platform – http://www.jppf.org/ import org.jppf.client.* import java.util.concurrent.Callable class Task implements Callable, Serializable { private static final long serialVersionUID = 1162L; public Object call() { println 'Executing Groovy' "Hello JPPF from Groovy" } } def client = new JPPFClient() def job = new JPPFJob() def task = new Task() job.addTask task def results = client.submit(job) for (t in results) { if (t.exception) throw t.exception println "Result: " + t.result } SpringOne2GX - 43
    44. Other High-Level Libraries: Gruple... – http://code.google.com/p/gruple – Gruple aims to provide a simple abstraction to allow programmers to coordinate and synchronize threads with ease – based on Tuplespaces • Tuplespaces provide the illusion of a shared memory on top of a message passing system, along with a small set of operations to greatly simplify parallel programming – Example Tuple: [fname:"Vanessa", lname:"Williams", project:"Gruple"] – Basic operations within a Tuplespace are: • put - insert a tuple into the space • get - read a tuple from the space (non-destructively) • take - take a tuple from the space (a destructive read) – Further reading: Eric Freeman, Susanne Hupfer, and Ken Arnold. JavaSpaces Principles, Patterns, and Practice, Addison Wesley, 1999 SpringOne2GX - 44
    45. Other High-Level Libraries: ...Gruple... – Mandelbrot example (included in Gruple download) ... Space space = SpaceService.getSpace("mandelbrot") Map template = createTaskTemplate() Map task String threadName = Thread.currentThread().getName() while(true) { ArrayList points task = space.take(template) println "Worker $threadName got task ${task['start']} for job ${task[' points = calculateMandelbrot(task) Map result = createResult(task['jobId'], task['start'], points) println "Worker $threadName writing result for task ${result['start']} space.put(result) } ... SpringOne2GX - 45
    46. Other High-Level Libraries: ...Gruple SpringOne2GX - 46
    47. Other High-Level Libraries: Cascading.groovy – API/DSL for executing tasks on a Hadoop cluster – http://www.cascading.org/ def assembly = builder.assembly(name: "wordcount") { eachTuple(args: ["line"], results: ["word"]) { regexSplitGenerator(declared: ["word"], pattern: /[.,]*s+/) } group(["word"]) everyGroup(args: ["word"], results: ["word", "count"]) { count() } group(["count"], reverse: true) } def map = builder.map() { source(name: "wordcount") { hfs(input) { text(["line"]) } } sink(name: "wordcount") { hfs(output) { text() } } } def flow = builder.flow(name: "wordcount", map: map, assembly: assembly) SpringOne2GX - 47
    48. Other High-Level Libraries: GridGain – Simple & productive to use grid computing platform – http://www.gridgain.com/ class GridHelloWorldGroovyTask extends GridTaskSplitAdapter<String, Integer> { Collection split(int gridSize, Object phrase) throws GridException { // ... } Object reduce(List results) throws GridException { // ... } } import static GridFactory.* start() def grid = getGrid() def future = grid.execute(GridHelloWorldGroovyTask, "Hello World") def phraseLen = future.get() stop(true) SpringOne2GX - 48
    49. Testing multi-threaded applications: ConTest... • Advanced Testing for Multi-Threaded Applications – Tool for testing, debugging, and coverage-measuring of concurrent programs (collects runtime statistics) – Systematically and transparently (using a java agent) schedules the execution of program threads in ways likely to reveal race conditions, deadlocks, and other intermittent bugs (collectively called synchronization problems) with higher than normal frequency – The ConTest run-time engine adds heuristically controlled conditional instructions (adjustable by a preferences file) that force thread switches, thus helping to reveal concurrent bugs. You can use existing tests and run ConTest multiple times – by default different heuristics used each time it is run • http://www.alphaworks.ibm.com/tech/contest SpringOne2GX - 49
    50. ...Testing multi-threaded applications: ConTest NUM = 5 ParalInc.groovy count = 0 def incThread = { n -> Thread.start{ sleep n*10 targetClasses = ParalInc //synchronized(ParalInc) { timeoutTampering = true count++ noiseFrequency = 500 //} strength = 10000 } } def threads = (1..NUM).collect(incThread) threads.each{ it.join() } assert count == NUM > groovyc ParalInc.groovy > java -javaagent:../../Lib/ConTest.jar -cp %GROOVY_JAR%;. ParalInc Exception in thread "main" Assertion failed: assert count == NUM | | | 4 | 5 false SpringOne2GX - 50
    51. GPARS 51 (c) ASERT 2009 SpringOne 2GX 2009. All rights reserved. Do not distribute without permission.
    52. gpars (formerly GParallelizer) • http://gpars.codehaus.org/ • Library classes and DSL sugar providing intuitive ways for Groovy developers to handle tasks concurrently. Logical parts: – Actors provide a Groovy implementation of Scala-like actors including "remote" actors on other machines – Dataflow Concurrency supports natural shared-memory © ASERT 2006-2009 concurrency model, using single-assignment variables – Asynchronizer extends the Java 1.5 built-in support for executor services to enable multi-threaded collection and closure processing – Parallelizer uses JSR-166y Parallel Arrays to enable multi-threaded collection processing – Safe a non-blocking mt-safe reference to mutable state that is inspired by "agents" in Clojure SpringOne2gx_Oct2009 - 52
    53. gpars/GParallelizer... // run multiple closures in parallel Asynchronizer.withAsynchronizer { assert [10, 20] == AsyncInvokerUtil.doInParallel( {calculateA()}, {calculateB()} ) © ASERT 2006-2009 } // multiply numbers asynchronously Parallelizer.withParallelizer(5) { def result = [1, 2, 3, 4, 5].collectAsync {it * 2} assert result == [2, 4, 6, 8, 10] } SpringOne2gx_Oct2009 - 53
    54. ...gpars/GParallelizer... // support for dataflow to avoid doing synchronisation import static org.gparallelizer.dataflow.DataFlow.thread final def x = new DataFlowVariable() final def y = new DataFlowVariable() final def z = new DataFlowVariable() © ASERT 2006-2009 thread { z << x.val + y.val println "Result: ${z.val}" } thread { x << 10 } thread { y << 5 } SpringOne2gx_Oct2009 - 54
    55. ...gpars/GParallelizer... // actor support import static org.gparallelizer.actors.pooledActors.PooledActors.* def me = actor { friend.send('Hi') react(10.seconds) { © ASERT 2006-2009 // continue conversation } } me.metaClass.onTimeout = {-> friend.send('I see, busy as usual. Never mind.')} me.start() SpringOne2gx_Oct2009 - 55
    56. ...gpars/GParallelizer // safe support import org.gparallelizer.actors.pooledActors.SafeVariable def jugMembers = new SafeVariable<List>(['Me']) //add Me jugMembers.send {it.add 'James'} //add James final Thread t1 = Thread.start { jugMembers.send {it.add 'Joe'} //add Joe © ASERT 2006-2009 } final Thread t2 = Thread.start { jugMembers << {it.add 'Dave'} //add Dave jugMembers << {it.add 'Alice'} //add Alice } [t1, t2]*.join() println jugMembers.val jugMembers.valAsync {println "Current members: $it"} System.in.read() jugMembers.stop() SpringOne2gx_Oct2009 - 56
    57. gpars for testing @Grab('net.sourceforge.htmlunit:htmlunit:2.6') import com.gargoylesoftware.htmlunit.WebClient @Grab('org.gparallelizer:GParallelizer:0.8.3') import static org.gparallelizer.Parallelizer.* def testCases = [ ['Home', 'Bart', 'Content 1'], ['Work', 'Homer', 'Content 2'], ['Travel', 'Marge', 'Content 3'], © ASERT 2006-2009 ['Food', 'Lisa', 'Content 4'] ] withParallelizer(3) { testCases.eachAsync{ category, author, content -> postAndCheck category, author, content } } private postAndCheck(category, author, content) { ... SpringOne2gx_Oct2009 - 57
    58. MORE INFORMATION 58 (c) ASERT 2009 SpringOne 2GX 2009. All rights reserved. Do not distribute without permission.
    59. More Information about Concurrency • Web sites – http://gpars.codehaus.org/ – http://g.oswego.edu/ Doug Lea's home page – http://gee.cs.oswego.edu/dl/concurrency-interest/ – http://jcip.net/ Companion site for Java Concurrency in Practice – http://www.eecs.usma.edu/webs/people/okasaki/pubs.html#cup98 Purely Functional Data Structures – http://delicious.com/kragen/concurrency Concurrency bookmark list – http://www.gotw.ca/publications/concurrency-ddj.htm The Free Lunch is Over, Herb Sutter – http://manticore.cs.uchicago.edu/papers/damp07.pdf – http://mitpress.mit.edu/catalog/item/default.asp?ttype=2&tid=10142 Concepts, Techniques, and Models of Computer Programming SpringOne2GX - 59
    60. More Information about Groovy • Web sites – http://groovy.codehaus.org – http://grails.codehaus.org – http://pleac.sourceforge.net/pleac_groovy (many examples) – http://www.asert.com.au/training/java/GV110.htm (workshop) • Mailing list for users – user@groovy.codehaus.org • Information portals – http://www.aboutgroovy.org – http://www.groovyblogs.org • Documentation (1000+ pages) – Getting Started Guide, User Guide, Developer Guide, Testing Guide, Cookbook Examples, Advanced Usage Guide • Books – Several to choose from ... SpringOne2GX - 60
    61. More Information: Groovy in Action SpringOne2GX - 61

    + Paul KingPaul King, 1 month ago

    custom

    989 views, 6 favs, 0 embeds more stats

    Dr Paul King presentation slides on "Groovy and Con more

    More info about this document

    CC Attribution License

    Go to text version

    • Total Views 989
      • 989 on SlideShare
      • 0 from embeds
    • Comments 0
    • Favorites 6
    • Downloads 50
    Most viewed embeds

    more

    All embeds

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories