GPars For Beginners
-
Upload
matt-passell -
Category
Technology
-
view
2.450 -
download
1
description
Transcript of GPars For Beginners
Matt Passell May 25, 2011
A Groovy approach to concurrent programming
For Beginners
About Me• Longtime Java developer (since '97)• Using Groovy on and off since early 2008• Concurrent programming enthusiast• Started software consultancy in 2007• More Groovy + Less Java = More Happy
Early History
● October 2008: Václav Pech creates GParallelizer
● September 2009: project renamed to GPars, moved to Codehaus, and Groovy luminaries join the team - (Dierk König, Paul King, Alex Tkachman, Russel Winder)
GPars Has a Logo Contest
http://gpars.codehaus.org/Logo+Contest
● October 2008: Václav Pech creates GParallelizer
● September 2009: project renamed to GPars, moved to Codehaus, and Groovy luminaries join the team (Dierk König, Paul King, Alex Tkachman, Russel Winder)
● December 2009: GPars gets a logo
● May 2010: 0.10 Release
● December 2010: 0.11 Release
● May 2011: 0.12 Beta 1
History
What GPars Provides● Code-level Helpers● Architecture-level Concepts● Protecting Shared Mutable State
What GPars Provides● Code-level Helpers
● Fork/Join● Map/Reduce (Parallel Collections)● Asynchronous Processing*
*not covered in this presentation
What GPars Provides● Architecture-level Concepts
● Dataflow Concurrency● Actors● Communicating Sequential Processes*
*not covered in this presentation
What GPars Provides● Protecting Shared Mutable State
● Agents● Software Transactional Memory*
*not covered in this presentation
Recurring Patterns● Favor immutability● Stateless code blocks (similar to
Servlets)
Fork/Join & Map/Reduce
Map Map Reduce
Fork Join Fork Join
Fork/Joindef list = [1, 2, 3, 4]GParsPool.withPool { assert [2, 4, 6, 8] == list.collectParallel { it * 2 } def animals = ['dog', 'ant', 'cat', 'whale'] println(animals.makeTransparent(). collect {it.toUpperCase()}. groupBy {it.contains 'A'})}
ParallelEnhancer.enhanceInstance(list)assert [2, 4, 6, 8] == list.collectParallel { it * 2 }
DemoParallelizer & DemoParallelEnhancer.groovy
Fork/Joindef list = [1, 2, 3, 4]GParsPool.withPool { assert [2, 4, 6, 8] == list.collectParallel { it * 2 } def animals = ['dog', 'ant', 'cat', 'whale'] println(animals.makeTransparent(). collect {it.toUpperCase()}. groupBy {it.contains 'A'})}
ParallelEnhancer.enhanceInstance(list)assert [2, 4, 6, 8] == list.collectParallel { it * 2 }
DemoParallelizer & DemoParallelEnhancer.groovy
Parallel Collections (Map/Reduce)
GParsPool.withPool { assert 20 == [1, 2, 3, 4, 5].parallel. filter {it % 2 == 0}. map {it ** 2}. reduce {a, b -> a + b} //sum the squares of even numbers
def urls = ['http://www.jroller.com', 'http://www.dzone.com', 'http://www.infoq.com'] println 'Sum of chars in all pages: ' + urls.parallel.map { it.toURL().text.size() }.sum()
//The equivalent using Fork/Join// println urls.collectParallel { it.toURL().text.size() }.sum()}
DemoMapReduce.groovy
Dataflow Concurrency● Modeled as a flow of data rather
than a flow of execution● Tree of dependent values
Like this?
How about this?
My Last Try
A
B
DED
C
When you put it that way...
A
B
DE
C
In Codedef flow = new DataFlows()task { flow.a = flow.b + flow.c }task { flow.b = flow.d + flow.e }task { flow.c = flow.d }task { flow.d = 17 }task { flow.e = 12 }assert 46 == flow.aprintln "flow.a = ${flow.a}"println "flow.b = ${flow.b}"
Actorsfinal def doubler = Actors.reactor { 2 * it}
Actor actor = Actors.actor { (1..10).each {doubler << it} int i = 0 loop { i += 1 if (i > 10) stop() else { react {message -> println "Double of $i = $message" } } }}
actor.join()doubler.stop()doubler.join()
DemoReactor2.groovy
Actorsfinal def doubler = Actors.reactor { 2 * it}
Actor actor = Actors.actor { (1..10).each {doubler << it} int i = 0 loop { i += 1 if (i > 10) stop() else { react {message -> println "Double of $i = $message" } } }}
actor.join()doubler.stop()doubler.join()
DemoReactor2.groovy
Agentsdef jugMembers = new Agent<List<String>>(['Me']) //add Me
jugMembers.send {it.add 'James'} //add James
//add Joe using the left-shift operatorfinal Thread t1 = Thread.start { jugMembers << { it.add 'Joe' } }
final Thread t2 = Thread.start { jugMembers {it.add 'Dave'} //use the implicit call() method jugMembers {it.add 'Alice'} //use the implicit call() method}
[t1, t2]*.join()println jugMembers.valjugMembers.valAsync {println "Current members: $it"}jugMembers.await()
DemoAgent.groovy
Resources● ReGinA Chapter 17 -
http://manning.com/koenig2/
● GPars User Guide -http://gpars.org/0.11/guide/index.html
● GPars User Mailing List - http://xircles.codehaus.org/lists/[email protected]
● Dierk König's presentation (Concurrent programming for you and me) -http://skillsmatter.com/podcast/groovy-grails/concurrent-programming-for-you-and-me
● Alex Miller's DevWorks article -http://www.ibm.com/developerworks/java/library/j-gpars/index.html
● Václav Pech's blog -http://www.jroller.com/vaclav/
Credits● GPars logo contest entries: various, late 2009. Author: various -
http://gpars.codehaus.org/Logo+Contest● Giant Fork: A metal four-pronged fork, Jun 2010. Author: dismal_denizen -
http://www.openclipart.org/detail/65749● Tree image: Linde von Linn, Jun 2006. Author: Stefan Wernli -
http://commons.wikimedia.org/wiki/File:Linde_von_linn.jpg● George Clooney image: Nov 2006. Author: James White/Corbis Outline -
http://bit.ly/iCSVal● Meryl Streep image: 2009. Author: unknown -
http://gosublogger.com/wp-content/uploads/2009/02/meryl-streep.jpg