SlideShare une entreprise Scribd logo
1  sur  26
Télécharger pour lire hors ligne
For Beginners
     A Groovy approach to concurrent programming




Matt Passell                               May 25, 2011
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
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)
●
    December 2009: GPars gets a logo
●
    May 2010: 0.10 Release
●
    December 2010: 0.11 Release
●
    May 2011: 0.12 Beta 1
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

    Fork   Join         Fork     Join




     Map          Map          Reduce
Fork/Join
def 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/Join
def 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                 C




D         E       D
When you put it that way...
             A




      B              C




E                D
In Code
def 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.a
println "flow.a = ${flow.a}"
println "flow.b = ${flow.b}"
Actors
final 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
Actors
final 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
Agents
def jugMembers = new Agent<List<String>>(['Me']) //add Me

jugMembers.send {it.add 'James'} //add James


//add Joe using the left-shift operator
final 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.val
jugMembers.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/user@gpars.codehaus.org
●
    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
Q&A


    http://bit.ly/gparsboston
mpassell@grovehillsoftware.com
http://blog.grovehillsoftware.com
        @softwaregrove

Contenu connexe

Tendances

VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access Runbook
Taha Shakeel
 
Real world scala
Real world scalaReal world scala
Real world scala
lunfu zhong
 

Tendances (20)

EcmaScript 6 - The future is here
EcmaScript 6 - The future is hereEcmaScript 6 - The future is here
EcmaScript 6 - The future is here
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
Psycopg2 - Connect to PostgreSQL using Python Script
Psycopg2 - Connect to PostgreSQL using Python ScriptPsycopg2 - Connect to PostgreSQL using Python Script
Psycopg2 - Connect to PostgreSQL using Python Script
 
ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
 
Map kit light
Map kit lightMap kit light
Map kit light
 
Swift Sequences & Collections
Swift Sequences & CollectionsSwift Sequences & Collections
Swift Sequences & Collections
 
Mozilla とブラウザゲーム
Mozilla とブラウザゲームMozilla とブラウザゲーム
Mozilla とブラウザゲーム
 
G*なクラウド 雲のかなたに ショートバージョン
G*なクラウド 雲のかなたに ショートバージョンG*なクラウド 雲のかなたに ショートバージョン
G*なクラウド 雲のかなたに ショートバージョン
 
Programming with Python and PostgreSQL
Programming with Python and PostgreSQLProgramming with Python and PostgreSQL
Programming with Python and PostgreSQL
 
"PostgreSQL and Python" Lightning Talk @EuroPython2014
"PostgreSQL and Python" Lightning Talk @EuroPython2014"PostgreSQL and Python" Lightning Talk @EuroPython2014
"PostgreSQL and Python" Lightning Talk @EuroPython2014
 
Python postgre sql a wonderful wedding
Python postgre sql   a wonderful weddingPython postgre sql   a wonderful wedding
Python postgre sql a wonderful wedding
 
The Ring programming language version 1.5.4 book - Part 40 of 185
The Ring programming language version 1.5.4 book - Part 40 of 185The Ring programming language version 1.5.4 book - Part 40 of 185
The Ring programming language version 1.5.4 book - Part 40 of 185
 
Talk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe ConversetTalk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe Converset
 
Mastering Kotlin Standard Library
Mastering Kotlin Standard LibraryMastering Kotlin Standard Library
Mastering Kotlin Standard Library
 
VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access Runbook
 
Minimizing Decision Fatigue to Improve Team Productivity
Minimizing Decision Fatigue to Improve Team ProductivityMinimizing Decision Fatigue to Improve Team Productivity
Minimizing Decision Fatigue to Improve Team Productivity
 
ECMAScript 6
ECMAScript 6ECMAScript 6
ECMAScript 6
 
Writing Clean Code in Swift
Writing Clean Code in SwiftWriting Clean Code in Swift
Writing Clean Code in Swift
 
Real world scala
Real world scalaReal world scala
Real world scala
 
Cycle.js: Functional and Reactive
Cycle.js: Functional and ReactiveCycle.js: Functional and Reactive
Cycle.js: Functional and Reactive
 

Similaire à GPars For Beginners

Javascript & Ajax Basics
Javascript & Ajax BasicsJavascript & Ajax Basics
Javascript & Ajax Basics
Richard Paul
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
David Padbury
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
偉格 高
 
All I know about rsc.io/c2go
All I know about rsc.io/c2goAll I know about rsc.io/c2go
All I know about rsc.io/c2go
Moriyoshi Koizumi
 

Similaire à GPars For Beginners (20)

Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
 
Javascript & Ajax Basics
Javascript & Ajax BasicsJavascript & Ajax Basics
Javascript & Ajax Basics
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Gpars workshop
Gpars workshopGpars workshop
Gpars workshop
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
 
Groovy
GroovyGroovy
Groovy
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Groovy and Grails talk
Groovy and Grails talkGroovy and Grails talk
Groovy and Grails talk
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 
Exploring Clojurescript
Exploring ClojurescriptExploring Clojurescript
Exploring Clojurescript
 
Cpp tutorial
Cpp tutorialCpp tutorial
Cpp tutorial
 
Implementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with SlickImplementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with Slick
 
How AngularDart & Firebase did an App together
How AngularDart & Firebase did an App togetherHow AngularDart & Firebase did an App together
How AngularDart & Firebase did an App together
 
JavaScript in 2015
JavaScript in 2015JavaScript in 2015
JavaScript in 2015
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
 
All I know about rsc.io/c2go
All I know about rsc.io/c2goAll I know about rsc.io/c2go
All I know about rsc.io/c2go
 
Tasks: you gotta know how to run them
Tasks: you gotta know how to run themTasks: you gotta know how to run them
Tasks: you gotta know how to run them
 
Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()
 

Dernier

Dernier (20)

Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 

GPars For Beginners

  • 1. For Beginners A Groovy approach to concurrent programming Matt Passell May 25, 2011
  • 2. 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
  • 3. 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)
  • 4. GPars Has a Logo Contest http://gpars.codehaus.org/Logo+Contest
  • 5. 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) ● December 2009: GPars gets a logo ● May 2010: 0.10 Release ● December 2010: 0.11 Release ● May 2011: 0.12 Beta 1
  • 6. What GPars Provides ● Code-level Helpers ● Architecture-level Concepts ● Protecting Shared Mutable State
  • 7. What GPars Provides ● Code-level Helpers ● Fork/Join ● Map/Reduce (Parallel Collections) ● Asynchronous Processing* *not covered in this presentation
  • 8. What GPars Provides ● Architecture-level Concepts ● Dataflow Concurrency ● Actors ● Communicating Sequential Processes* *not covered in this presentation
  • 9. What GPars Provides ● Protecting Shared Mutable State ● Agents ● Software Transactional Memory* *not covered in this presentation
  • 10. Recurring Patterns ● Favor immutability ● Stateless code blocks (similar to Servlets)
  • 11. Fork/Join & Map/Reduce Fork Join Fork Join Map Map Reduce
  • 12. Fork/Join def 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
  • 13. Fork/Join def 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
  • 14. 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
  • 15. Dataflow Concurrency ● Modeled as a flow of data rather than a flow of execution ● Tree of dependent values
  • 18. My Last Try A B C D E D
  • 19. When you put it that way... A B C E D
  • 20. In Code def 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.a println "flow.a = ${flow.a}" println "flow.b = ${flow.b}"
  • 21. Actors final 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
  • 22. Actors final 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
  • 23. Agents def jugMembers = new Agent<List<String>>(['Me']) //add Me jugMembers.send {it.add 'James'} //add James //add Joe using the left-shift operator final 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.val jugMembers.valAsync {println "Current members: $it"} jugMembers.await() DemoAgent.groovy
  • 24. 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/user@gpars.codehaus.org ● 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/
  • 25. 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
  • 26. Q&A http://bit.ly/gparsboston mpassell@grovehillsoftware.com http://blog.grovehillsoftware.com @softwaregrove