DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Event-Driven Fractals
  • Why "Polyglot Programming" or "Do It Yourself Programming Languages" or "Language Oriented Programming" sucks?
  • Java vs. Python Comparison: The Battle of Best Programming Language in 2021
  • Floyd's Cycle Algorithm for Fraud Detection in Java Systems

Trending

  • Advancing Your Software Engineering Career in 2025
  • Implementing Explainable AI in CRM Using Stream Processing
  • Designing a Java Connector for Software Integrations
  • Securing the Future: Best Practices for Privacy and Data Governance in LLMOps
  1. DZone
  2. Coding
  3. Languages
  4. Concurrent Programming in Groovy

Concurrent Programming in Groovy

By 
Mitch Pronschinske user avatar
Mitch Pronschinske
·
Feb. 22, 10 · Interview
Likes (2)
Comment
Save
Tweet
Share
53.1K Views

Join the DZone community and get the full member experience.

Join For Free

It seems that the Groovy has a project for just about anything.  That's one of the reasons why the language is so popular.  The GPars library is an especially useful project in this new era of mult-core processors and concurrent programming.  Formerly known as GParallelizer, GPars offers a framework for handling tasks concurrently and asynchronously while safe-guarding mutable values.  DZone recently got an update on the project's latest news from project lead Václav Pech, and we've provided some examples of GPars concepts.


GPars uses some of the best concepts from emerging languages and implements them for Groovy.  Its actor support was inspired by the Actors library in Scala and the SafeVariable class in GPars was inspired by Agents in Clojure.  The Groovy-based APIs in GPars are used to declare which parts of the code should be run concurrently.  Objects can be enhanced with asynchronous methods to perform collections-based operations in parallel based on the fork/join model.  GPars also has a Dataflow concurrency model that offers an alternative model that is inherently safe and robust due to algorithms that prevent having to deal with live-locks and race-conditions.  The SafeVariable class is another technology in GPars that alleviates problems with concurrency by providing a non-blocking mt-safe reference to mutable state when Java libraries are integrated.  Finally the Parallelizer, Asynchronizer, and Actors are some of the most interesting concepts in GPars.


Actors

Actors can be generated quickly to consume and send messages between each other even across distributed machines.  You can build a messaging-based concurrency model with actors that are not limited by the number of threads.  What was once only available to Scala developers, GPars now brings to Java and Groovy developers.


Actors perform three different operations - send messages, receive messages and create new actors.  New actors are created with the actor() method passing in the actor's body as a closure parameter.  Inside the actor's body loop() is used to iterate, react() to receive messages, and reply() to send a message to the actor, which has sent the currently processed message.  Here is how to create an actor that prints out all messages that it receives:

import static groovyx.gpars.actor.Actors.*
def console = actor {
    loop {
        react {
            println it
        }
    }
}

The loop() method ensures that the actor doesn't stop after processing the first message.


Messages are sent using the send() method or the << operator.  Here is an example of the sendAndWait () method in a message:

actor << 'Message'
actor.send 'Message'
def reply1 = actor.sendAndWait('Message')
def reply2 = actor.sendAndWait(10, TimeUnit.SECONDS, 'Message')
def reply3 = actor.sendAndWait(10.seconds, 'Message')

The sendAndWait() family blocks the caller until a reply from the actor becomes available.  The reply is returned from sendAndWait() as a return value.  


For non-blocking message retrieval, calling the react() method, with or without a timeout parameter, from within the actor's code will consume the next message from the actor's inbox:

println 'Waiting for a gift'
react {gift ->
    if (myWife.likes gift) reply 'Thank you!'
}


Here is a more 'real world' example of an event-driven actor that receives two numeric messages, generates a sum, and sends the result to the console actor:

import static groovyx.gpars.actor.Actors.*
//not necessary, just showing that a single-threaded pool can still handle multiple actors
defaultPooledActorGroup.resize 1
final def console = actor {
    loop {
        react {
            println 'Result: ' + it
        }
    }
}
final def calculator = actor {
    react {a ->
        react {b ->
            console.send(a + b)
        }
    }
}
calculator.send 2
calculator.send 3
calculator.join()


Since Actors can share a relatively small thread pool, they bypass the threading limitations of the JVM and don't require excessive system resources even if an application consists of thousands of actors.  There are some more sophisticated actor examples on the old GParallelizer wiki and there's also a nice article on the key concepts behind actors in erlang and scala.  The documentation on GPars Actors can be found here.


Asynchronizer

A major feature of GPars is the Asynchronizer class, which runs tasks asynchronously in the background.  It enables a Java Executor Service-based DSL on collections and closures.  Inside the Asynchronizer.doParallel() blocks, asynchronous methods can be added to the closures.  async() creates a variant of the supplied closure returning a future for the potential return value when invoked.  callAsync() calls a closure in a separate thread supplying the given arguments and also returns a future for the potential value.  Here is one example of Asynchronizer use:

Asynchronizer.doParallel() {
    Closure longLastingCalculation = {calculate()}
    Closure fastCalculation = longLastingCalculation.async()  //create a new closure, which starts the original closure on a thread pool
    Future result=fastCalculation()                           //returns almost immediately
    //do stuff while calculation performs …
    println result.get()
}


Parallelizer

Finally, there's the Parallelizer, which is a concurrent collection processor.  The common pattern to process collections takes elements sequentially, one at a time.  This algorithm however, won't work well on multi-core hardware.  The min() function on a dual-core chip can only leverage 50% of the computing power - 25% for a quad-core.  Instead, GPars uses a tree-like structure for parallel processing.  The Parallelizer class enables a ParallelArray(from JSR-166y)-based DSL on collections.  Here is a use exapmle:

doParallel {
    def selfPortraits = images.findAllParallel{it.contains me}.collectParallel {it.resize()}

    //a map-reduce functional style
    def smallestSelfPortrait = images.parallel.filter{it.contains me}.map{it.resize()}.min{it.sizeInMB}
} 


Václav Pech told DZone that GPars currently has two new people joining the project - Jon Kerridge and Kevin Chalmers.   The two developers are bringing their JCSP Groovy library with them into GPars.  Pech said, "Apart from experimenting with the CSP concept, we will also enhance actor remoting and polish a couple of rough edges on the APIs. The documentation and especially the samples also deserve more attention."  GPars' documentation is already quite robust.


Pech says there quite a few issues queued up in their JIRA, but the previously listed issues remain the top priorities.  Depending on the amount of time required to make progress with CSP, the GPars 1.0 release might happen in the summer says Pech.  GPars is also developed by Alex Tkachman, a leading developer on the Groovy++ project.  In an with Andres Almiray, Tkachman said that some of the work that comes out of Groovy++ might be assimilated into GPars, but no plans are in place yet since Groovy++ developers are still experimenting.

Groovy (programming language) Concept (generic programming) dev Java (programming language) Library Scala (programming language) Documentation Algorithm Blocks

Opinions expressed by DZone contributors are their own.

Related

  • Event-Driven Fractals
  • Why "Polyglot Programming" or "Do It Yourself Programming Languages" or "Language Oriented Programming" sucks?
  • Java vs. Python Comparison: The Battle of Best Programming Language in 2021
  • Floyd's Cycle Algorithm for Fraud Detection in Java Systems

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!