26
Matt Passell May 25, 2011 A Groovy approach to concurrent programming For Beginners

GPars For Beginners

Embed Size (px)

DESCRIPTION

The GPars (Groovy Parallel Systems) project provides multiple abstractions for concurrent, parallel programming in Groovy and Java. Rather than dealing directly with threads, synchronization, and locks, or even the java.util.concurrent classes added in Java 5, the project allows you to think in terms of actors, data flows, or composable asynchronous functions (to name a few). In this talk, I covered the basics of GPars, including what it's like to learn to use it. Although I've done a fair amount of concurrent programming, I've just started using GPars. As such, this talk should be suitable for Groovy beginners.

Citation preview

Page 1: GPars For Beginners

Matt Passell May 25, 2011

A Groovy approach to concurrent programming

For Beginners

Page 2: GPars 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

Page 3: GPars For Beginners

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)

Page 4: GPars For Beginners

GPars Has a Logo Contest

http://gpars.codehaus.org/Logo+Contest

Page 5: GPars For Beginners

● 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

Page 6: GPars For Beginners

What GPars Provides● Code-level Helpers● Architecture-level Concepts● Protecting Shared Mutable State

Page 7: GPars For Beginners

What GPars Provides● Code-level Helpers

● Fork/Join● Map/Reduce (Parallel Collections)● Asynchronous Processing*

*not covered in this presentation

Page 8: GPars For Beginners

What GPars Provides● Architecture-level Concepts

● Dataflow Concurrency● Actors● Communicating Sequential Processes*

*not covered in this presentation

Page 9: GPars For Beginners

What GPars Provides● Protecting Shared Mutable State

● Agents● Software Transactional Memory*

*not covered in this presentation

Page 10: GPars For Beginners

Recurring Patterns● Favor immutability● Stateless code blocks (similar to

Servlets)

Page 11: GPars For Beginners

Fork/Join & Map/Reduce

Map Map Reduce

Fork Join Fork Join

Page 12: GPars For Beginners

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

Page 13: GPars For Beginners

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

Page 14: GPars For Beginners

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

Page 15: GPars For Beginners

Dataflow Concurrency● Modeled as a flow of data rather

than a flow of execution● Tree of dependent values

Page 16: GPars For Beginners

Like this?

Page 17: GPars For Beginners

How about this?

Page 18: GPars For Beginners

My Last Try

A

B

DED

C

Page 19: GPars For Beginners

When you put it that way...

A

B

DE

C

Page 20: GPars For Beginners

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}"

Page 21: GPars For Beginners

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

Page 22: GPars For Beginners

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

Page 23: GPars For Beginners

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

Page 24: GPars For Beginners

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/

Page 25: GPars For Beginners

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

Page 26: GPars For Beginners

Q & A

http://bit.ly/[email protected]://blog.grovehillsoftware.com

@softwaregrove